OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/apps/ephemeral_app_browsertest.h" | 5 #include "chrome/browser/apps/ephemeral_app_browsertest.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
| 9 #include "apps/app_restore_service.h" |
9 #include "apps/saved_files_service.h" | 10 #include "apps/saved_files_service.h" |
10 #include "base/files/scoped_temp_dir.h" | 11 #include "base/files/scoped_temp_dir.h" |
11 #include "base/scoped_observer.h" | 12 #include "base/scoped_observer.h" |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "chrome/browser/apps/app_browsertest_util.h" | 14 #include "chrome/browser/apps/app_browsertest_util.h" |
| 15 #include "chrome/browser/apps/ephemeral_app_service.h" |
14 #include "chrome/browser/extensions/api/file_system/file_system_api.h" | 16 #include "chrome/browser/extensions/api/file_system/file_system_api.h" |
15 #include "chrome/browser/extensions/app_sync_data.h" | 17 #include "chrome/browser/extensions/app_sync_data.h" |
16 #include "chrome/browser/extensions/extension_service.h" | 18 #include "chrome/browser/extensions/extension_service.h" |
17 #include "chrome/browser/extensions/extension_sync_service.h" | 19 #include "chrome/browser/extensions/extension_sync_service.h" |
18 #include "chrome/browser/extensions/extension_test_message_listener.h" | 20 #include "chrome/browser/extensions/extension_test_message_listener.h" |
19 #include "chrome/browser/extensions/extension_util.h" | 21 #include "chrome/browser/extensions/extension_util.h" |
20 #include "chrome/browser/notifications/desktop_notification_service.h" | 22 #include "chrome/browser/notifications/desktop_notification_service.h" |
21 #include "chrome/browser/notifications/desktop_notification_service_factory.h" | 23 #include "chrome/browser/notifications/desktop_notification_service_factory.h" |
22 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
23 #include "chrome/common/extensions/api/alarms.h" | 25 #include "chrome/common/extensions/api/alarms.h" |
(...skipping 22 matching lines...) Expand all Loading... |
46 using extensions::ExtensionPrefs; | 48 using extensions::ExtensionPrefs; |
47 using extensions::ExtensionRegistry; | 49 using extensions::ExtensionRegistry; |
48 using extensions::ExtensionRegistryObserver; | 50 using extensions::ExtensionRegistryObserver; |
49 using extensions::ExtensionSystem; | 51 using extensions::ExtensionSystem; |
50 using extensions::Manifest; | 52 using extensions::Manifest; |
51 | 53 |
52 namespace { | 54 namespace { |
53 | 55 |
54 namespace alarms = extensions::api::alarms; | 56 namespace alarms = extensions::api::alarms; |
55 | 57 |
56 const char kDispatchEventTestApp[] = "ephemeral_apps/dispatch_event"; | |
57 const char kNotificationsTestApp[] = "ephemeral_apps/notification_settings"; | |
58 const char kFileSystemTestApp[] = "ephemeral_apps/filesystem_retain_entries"; | 58 const char kFileSystemTestApp[] = "ephemeral_apps/filesystem_retain_entries"; |
59 | 59 |
60 typedef std::vector<message_center::Notifier*> NotifierList; | 60 typedef std::vector<message_center::Notifier*> NotifierList; |
61 | 61 |
62 bool IsNotifierInList(const message_center::NotifierId& notifier_id, | 62 bool IsNotifierInList(const message_center::NotifierId& notifier_id, |
63 const NotifierList& notifiers) { | 63 const NotifierList& notifiers) { |
64 for (NotifierList::const_iterator it = notifiers.begin(); | 64 for (NotifierList::const_iterator it = notifiers.begin(); |
65 it != notifiers.end(); ++it) { | 65 it != notifiers.end(); ++it) { |
66 const message_center::Notifier* notifier = *it; | 66 const message_center::Notifier* notifier = *it; |
67 if (notifier->notifier_id == notifier_id) | 67 if (notifier->notifier_id == notifier_id) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 | 116 |
117 } // namespace | 117 } // namespace |
118 | 118 |
119 | 119 |
120 // EphemeralAppTestBase: | 120 // EphemeralAppTestBase: |
121 | 121 |
122 const char EphemeralAppTestBase::kMessagingReceiverApp[] = | 122 const char EphemeralAppTestBase::kMessagingReceiverApp[] = |
123 "ephemeral_apps/messaging_receiver"; | 123 "ephemeral_apps/messaging_receiver"; |
124 const char EphemeralAppTestBase::kMessagingReceiverAppV2[] = | 124 const char EphemeralAppTestBase::kMessagingReceiverAppV2[] = |
125 "ephemeral_apps/messaging_receiver2"; | 125 "ephemeral_apps/messaging_receiver2"; |
| 126 const char EphemeralAppTestBase::kDispatchEventTestApp[] = |
| 127 "ephemeral_apps/dispatch_event"; |
| 128 const char EphemeralAppTestBase::kNotificationsTestApp[] = |
| 129 "ephemeral_apps/notification_settings"; |
126 | 130 |
127 EphemeralAppTestBase::EphemeralAppTestBase() {} | 131 EphemeralAppTestBase::EphemeralAppTestBase() {} |
128 | 132 |
129 EphemeralAppTestBase::~EphemeralAppTestBase() {} | 133 EphemeralAppTestBase::~EphemeralAppTestBase() {} |
130 | 134 |
131 void EphemeralAppTestBase::SetUpCommandLine(base::CommandLine* command_line) { | 135 void EphemeralAppTestBase::SetUpCommandLine(base::CommandLine* command_line) { |
132 // Skip PlatformAppBrowserTest, which sets different values for the switches | 136 // Skip PlatformAppBrowserTest, which sets different values for the switches |
133 // below. | 137 // below. |
134 ExtensionBrowserTest::SetUpCommandLine(command_line); | 138 ExtensionBrowserTest::SetUpCommandLine(command_line); |
135 | 139 |
136 // Make event pages get suspended immediately. | 140 // Make event pages get suspended immediately. |
137 command_line->AppendSwitchASCII( | 141 command_line->AppendSwitchASCII( |
138 extensions::switches::kEventPageIdleTime, "10"); | 142 extensions::switches::kEventPageIdleTime, "10"); |
139 command_line->AppendSwitchASCII( | 143 command_line->AppendSwitchASCII( |
140 extensions::switches::kEventPageSuspendingTime, "10"); | 144 extensions::switches::kEventPageSuspendingTime, "10"); |
141 | 145 |
142 // Enable ephemeral apps flag. | 146 // Enable ephemeral apps flag. |
143 command_line->AppendSwitch(switches::kEnableEphemeralApps); | 147 command_line->AppendSwitch(switches::kEnableEphemeralApps); |
144 } | 148 } |
145 | 149 |
| 150 void EphemeralAppTestBase::SetUpOnMainThread() { |
| 151 PlatformAppBrowserTest::SetUpOnMainThread(); |
| 152 |
| 153 // Unload ephemeral apps immediately after they stop running in tests. |
| 154 EphemeralAppService::Get(profile())->set_unload_delay_for_test(0); |
| 155 } |
| 156 |
146 base::FilePath EphemeralAppTestBase::GetTestPath(const char* test_path) { | 157 base::FilePath EphemeralAppTestBase::GetTestPath(const char* test_path) { |
147 return test_data_dir_.AppendASCII("platform_apps").AppendASCII(test_path); | 158 return test_data_dir_.AppendASCII("platform_apps").AppendASCII(test_path); |
148 } | 159 } |
149 | 160 |
150 const Extension* EphemeralAppTestBase::InstallEphemeralApp( | 161 const Extension* EphemeralAppTestBase::InstallEphemeralApp( |
151 const char* test_path, Manifest::Location manifest_location) { | 162 const char* test_path, Manifest::Location manifest_location) { |
152 const Extension* extension = InstallEphemeralAppWithSourceAndFlags( | 163 const Extension* extension = InstallEphemeralAppWithSourceAndFlags( |
153 GetTestPath(test_path), 1, manifest_location, Extension::NO_FLAGS); | 164 GetTestPath(test_path), 1, manifest_location, Extension::NO_FLAGS); |
154 EXPECT_TRUE(extension); | 165 EXPECT_TRUE(extension); |
155 if (extension) | 166 if (extension) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 extensions::CrxInstaller* crx_installer = NULL; | 212 extensions::CrxInstaller* crx_installer = NULL; |
202 content::WindowedNotificationObserver windowed_observer( | 213 content::WindowedNotificationObserver windowed_observer( |
203 chrome::NOTIFICATION_CRX_INSTALLER_DONE, | 214 chrome::NOTIFICATION_CRX_INSTALLER_DONE, |
204 content::Source<extensions::CrxInstaller>(crx_installer)); | 215 content::Source<extensions::CrxInstaller>(crx_installer)); |
205 ExtensionService* service = | 216 ExtensionService* service = |
206 ExtensionSystem::Get(profile())->extension_service(); | 217 ExtensionSystem::Get(profile())->extension_service(); |
207 EXPECT_TRUE(service->UpdateExtension(app_id, app_v2_path, true, | 218 EXPECT_TRUE(service->UpdateExtension(app_id, app_v2_path, true, |
208 &crx_installer)); | 219 &crx_installer)); |
209 windowed_observer.Wait(); | 220 windowed_observer.Wait(); |
210 | 221 |
211 return service->GetExtensionById(app_id, false); | 222 return ExtensionRegistry::Get(profile()) |
| 223 ->GetExtensionById(app_id, ExtensionRegistry::EVERYTHING); |
212 } | 224 } |
213 | 225 |
214 void EphemeralAppTestBase::PromoteEphemeralApp( | 226 void EphemeralAppTestBase::PromoteEphemeralApp( |
215 const extensions::Extension* app) { | 227 const extensions::Extension* app) { |
216 ExtensionService* extension_service = | 228 ExtensionService* extension_service = |
217 ExtensionSystem::Get(profile())->extension_service(); | 229 ExtensionSystem::Get(profile())->extension_service(); |
218 ASSERT_TRUE(extension_service); | 230 ASSERT_TRUE(extension_service); |
219 extension_service->PromoteEphemeralApp(app, false); | 231 extension_service->PromoteEphemeralApp(app, false); |
220 } | 232 } |
221 | 233 |
222 void EphemeralAppTestBase::CloseApp(const std::string& app_id) { | 234 void EphemeralAppTestBase::CloseApp(const std::string& app_id) { |
223 content::WindowedNotificationObserver event_page_destroyed_signal( | |
224 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | |
225 content::Source<Profile>(profile())); | |
226 | |
227 EXPECT_EQ(1U, GetAppWindowCountForApp(app_id)); | 235 EXPECT_EQ(1U, GetAppWindowCountForApp(app_id)); |
228 apps::AppWindow* app_window = GetFirstAppWindowForApp(app_id); | 236 apps::AppWindow* app_window = GetFirstAppWindowForApp(app_id); |
229 ASSERT_TRUE(app_window); | 237 ASSERT_TRUE(app_window); |
230 CloseAppWindow(app_window); | 238 CloseAppWindow(app_window); |
| 239 } |
231 | 240 |
232 event_page_destroyed_signal.Wait(); | 241 void EphemeralAppTestBase::CloseAppWaitForUnload(const std::string& app_id) { |
| 242 // Ephemeral apps are unloaded from extension system after they stop running. |
| 243 content::WindowedNotificationObserver unloaded_signal( |
| 244 chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, |
| 245 content::Source<Profile>(profile())); |
| 246 CloseApp(app_id); |
| 247 unloaded_signal.Wait(); |
233 } | 248 } |
234 | 249 |
235 void EphemeralAppTestBase::EvictApp(const std::string& app_id) { | 250 void EphemeralAppTestBase::EvictApp(const std::string& app_id) { |
236 // Uninstall the app, which is what happens when ephemeral apps get evicted | 251 // Uninstall the app, which is what happens when ephemeral apps get evicted |
237 // from the cache. | 252 // from the cache. |
238 content::WindowedNotificationObserver uninstalled_signal( | 253 content::WindowedNotificationObserver uninstalled_signal( |
239 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, | 254 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, |
240 content::Source<Profile>(profile())); | 255 content::Source<Profile>(profile())); |
241 | 256 |
242 ExtensionService* service = | 257 ExtensionService* service = |
243 ExtensionSystem::Get(profile())->extension_service(); | 258 ExtensionSystem::Get(profile())->extension_service(); |
244 ASSERT_TRUE(service); | 259 ASSERT_TRUE(service); |
245 service->UninstallExtension(app_id, false, NULL); | 260 service->UninstallExtension(app_id, false, NULL); |
246 | 261 |
247 uninstalled_signal.Wait(); | 262 uninstalled_signal.Wait(); |
248 } | 263 } |
249 | 264 |
250 // EphemeralAppBrowserTest: | 265 // EphemeralAppBrowserTest: |
251 | 266 |
252 class EphemeralAppBrowserTest : public EphemeralAppTestBase { | 267 class EphemeralAppBrowserTest : public EphemeralAppTestBase { |
253 protected: | 268 protected: |
254 bool LaunchAppAndRunTest(const Extension* app, const char* test_name) { | 269 bool LaunchAppAndRunTest(const Extension* app, const char* test_name) { |
| 270 // Ephemeral apps are unloaded after they are closed. Ensure they are |
| 271 // enabled before launch. |
| 272 ExtensionService* service = |
| 273 ExtensionSystem::Get(profile())->extension_service(); |
| 274 service->EnableExtension(app->id()); |
| 275 |
255 ExtensionTestMessageListener launched_listener("launched", true); | 276 ExtensionTestMessageListener launched_listener("launched", true); |
256 LaunchPlatformApp(app); | 277 LaunchPlatformApp(app); |
257 if (!launched_listener.WaitUntilSatisfied()) { | 278 if (!launched_listener.WaitUntilSatisfied()) { |
258 message_ = "Failed to receive launched message from test"; | 279 message_ = "Failed to receive launched message from test"; |
259 return false; | 280 return false; |
260 } | 281 } |
261 | 282 |
262 ResultCatcher catcher; | 283 ResultCatcher catcher; |
263 launched_listener.Reply(test_name); | 284 launched_listener.Reply(test_name); |
264 | 285 |
265 bool result = catcher.GetNextResult(); | 286 bool result = catcher.GetNextResult(); |
266 message_ = catcher.message(); | 287 message_ = catcher.message(); |
267 | 288 |
268 CloseApp(app->id()); | 289 CloseAppWaitForUnload(app->id()); |
269 return result; | 290 return result; |
270 } | 291 } |
271 | 292 |
| 293 // Verify that the event page of the app has not been loaded. |
272 void VerifyAppNotLoaded(const std::string& app_id) { | 294 void VerifyAppNotLoaded(const std::string& app_id) { |
273 EXPECT_FALSE(ExtensionSystem::Get(profile())-> | 295 EXPECT_FALSE(ExtensionSystem::Get(profile())-> |
274 process_manager()->GetBackgroundHostForExtension(app_id)); | 296 process_manager()->GetBackgroundHostForExtension(app_id)); |
275 } | 297 } |
276 | 298 |
| 299 // Verify that after ephemeral apps stop running, they reside in extension |
| 300 // system in a disabled and unloaded state. |
| 301 void VerifyInactiveEphemeralApp(const std::string& app_id) { |
| 302 EXPECT_TRUE( |
| 303 ExtensionRegistry::Get(profile())->disabled_extensions().Contains( |
| 304 app_id)); |
| 305 |
| 306 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); |
| 307 EXPECT_TRUE(prefs->IsExtensionDisabled(app_id)); |
| 308 EXPECT_NE(0, |
| 309 prefs->GetDisableReasons(app_id) & |
| 310 Extension::DISABLE_INACTIVE_EPHEMERAL_APP); |
| 311 } |
| 312 |
| 313 // Verify the state of an app that has been promoted from an ephemeral to a |
| 314 // fully installed app. |
| 315 void VerifyPromotedApp(const std::string& app_id, |
| 316 ExtensionRegistry::IncludeFlag expected_set) { |
| 317 const Extension* app = ExtensionRegistry::Get(profile()) |
| 318 ->GetExtensionById(app_id, expected_set); |
| 319 ASSERT_TRUE(app) << "App not found in expected set: " << expected_set; |
| 320 |
| 321 // The app should not be ephemeral. |
| 322 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); |
| 323 ASSERT_TRUE(prefs); |
| 324 EXPECT_FALSE(prefs->IsEphemeralApp(app_id)); |
| 325 EXPECT_EQ(0, |
| 326 prefs->GetDisableReasons(app_id) & |
| 327 Extension::DISABLE_INACTIVE_EPHEMERAL_APP); |
| 328 |
| 329 // Check sort ordinals. |
| 330 extensions::AppSorting* app_sorting = prefs->app_sorting(); |
| 331 EXPECT_TRUE(app_sorting->GetAppLaunchOrdinal(app_id).IsValid()); |
| 332 EXPECT_TRUE(app_sorting->GetPageOrdinal(app_id).IsValid()); |
| 333 } |
| 334 |
| 335 // Dispatch a fake alarm event to the app. |
277 void DispatchAlarmEvent(EventRouter* event_router, | 336 void DispatchAlarmEvent(EventRouter* event_router, |
278 const std::string& app_id) { | 337 const std::string& app_id) { |
279 alarms::Alarm dummy_alarm; | 338 alarms::Alarm dummy_alarm; |
280 dummy_alarm.name = "test_alarm"; | 339 dummy_alarm.name = "test_alarm"; |
281 | 340 |
282 scoped_ptr<base::ListValue> args(new base::ListValue()); | 341 scoped_ptr<base::ListValue> args(new base::ListValue()); |
283 args->Append(dummy_alarm.ToValue().release()); | 342 args->Append(dummy_alarm.ToValue().release()); |
284 scoped_ptr<Event> event(new Event(alarms::OnAlarm::kEventName, | 343 scoped_ptr<Event> event(new Event(alarms::OnAlarm::kEventName, |
285 args.Pass())); | 344 args.Pass())); |
286 | 345 |
287 event_router->DispatchEventToExtension(app_id, event.Pass()); | 346 event_router->DispatchEventToExtension(app_id, event.Pass()); |
288 } | 347 } |
289 | 348 |
| 349 // Simulates the scenario where an app is installed, via the normal |
| 350 // installation route, on top of an ephemeral app. This can occur due to race |
| 351 // conditions. |
290 const Extension* ReplaceEphemeralApp(const std::string& app_id, | 352 const Extension* ReplaceEphemeralApp(const std::string& app_id, |
291 const char* test_path) { | 353 const char* test_path, |
292 return UpdateExtensionWaitForIdle(app_id, GetTestPath(test_path), 0); | 354 int expected_enabled_change) { |
| 355 return UpdateExtensionWaitForIdle( |
| 356 app_id, GetTestPath(test_path), expected_enabled_change); |
293 } | 357 } |
294 | 358 |
295 void VerifyPromotedApp(const std::string& app_id, | 359 void DisableEphemeralApp(const Extension* app, |
296 ExtensionRegistry::IncludeFlag expected_set) { | 360 Extension::DisableReason disable_reason) { |
297 const Extension* app = ExtensionRegistry::Get(profile())->GetExtensionById( | 361 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); |
298 app_id, expected_set); | 362 |
| 363 // Disabling due to a permissions increase also involves setting the |
| 364 // DidExtensionEscalatePermissions flag. |
| 365 if (disable_reason == Extension::DISABLE_PERMISSIONS_INCREASE) |
| 366 prefs->SetDidExtensionEscalatePermissions(app, true); |
| 367 |
| 368 ExtensionSystem::Get(profile())->extension_service()->DisableExtension( |
| 369 app->id(), disable_reason); |
| 370 |
| 371 ASSERT_TRUE( |
| 372 ExtensionRegistry::Get(profile())->disabled_extensions().Contains( |
| 373 app->id())); |
| 374 } |
| 375 |
| 376 void PromoteEphemeralAppAndVerify( |
| 377 const Extension* app, |
| 378 ExtensionRegistry::IncludeFlag expected_set) { |
299 ASSERT_TRUE(app); | 379 ASSERT_TRUE(app); |
300 | 380 |
301 // The app should not be ephemeral. | 381 // Ephemeral apps should not be synced. |
| 382 scoped_ptr<AppSyncData> sync_change = GetFirstSyncChangeForApp(app->id()); |
| 383 EXPECT_FALSE(sync_change.get()); |
| 384 |
| 385 // Promote the app to a regular installed app. |
| 386 InstallObserver installed_observer(profile()); |
| 387 PromoteEphemeralApp(app); |
| 388 VerifyPromotedApp(app->id(), expected_set); |
| 389 |
| 390 // Check the notification parameters. |
| 391 const InstallObserver::InstallParameters& params = |
| 392 installed_observer.Last(); |
| 393 EXPECT_EQ(app->id(), params.id); |
| 394 EXPECT_TRUE(params.is_update); |
| 395 EXPECT_TRUE(params.from_ephemeral); |
| 396 |
| 397 // The installation should now be synced. |
| 398 sync_change = GetFirstSyncChangeForApp(app->id()); |
| 399 VerifySyncChange(sync_change.get(), |
| 400 expected_set == ExtensionRegistry::ENABLED); |
| 401 } |
| 402 |
| 403 void PromoteEphemeralAppFromSyncAndVerify( |
| 404 const Extension* app, |
| 405 bool enable_from_sync, |
| 406 ExtensionRegistry::IncludeFlag expected_set) { |
| 407 ASSERT_TRUE(app); |
| 408 |
| 409 // Simulate an install from sync. |
| 410 const syncer::StringOrdinal kAppLaunchOrdinal("x"); |
| 411 const syncer::StringOrdinal kPageOrdinal("y"); |
| 412 AppSyncData app_sync_data(*app, |
| 413 enable_from_sync, |
| 414 false /* incognito enabled */, |
| 415 false /* remote install */, |
| 416 kAppLaunchOrdinal, |
| 417 kPageOrdinal, |
| 418 extensions::LAUNCH_TYPE_REGULAR); |
| 419 |
| 420 std::string app_id = app->id(); |
| 421 app = NULL; |
| 422 |
| 423 ExtensionSyncService* sync_service = ExtensionSyncService::Get(profile()); |
| 424 sync_service->ProcessAppSyncData(app_sync_data); |
| 425 |
| 426 // Verify the installation. |
| 427 VerifyPromotedApp(app_id, expected_set); |
| 428 |
| 429 // The sort ordinals from sync should not be overridden. |
302 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); | 430 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); |
303 ASSERT_TRUE(prefs); | |
304 EXPECT_FALSE(prefs->IsEphemeralApp(app_id)); | |
305 | |
306 // Check sort ordinals. | |
307 extensions::AppSorting* app_sorting = prefs->app_sorting(); | 431 extensions::AppSorting* app_sorting = prefs->app_sorting(); |
308 EXPECT_TRUE(app_sorting->GetAppLaunchOrdinal(app_id).IsValid()); | 432 EXPECT_TRUE( |
309 EXPECT_TRUE(app_sorting->GetPageOrdinal(app_id).IsValid()); | 433 app_sorting->GetAppLaunchOrdinal(app_id).Equals(kAppLaunchOrdinal)); |
| 434 EXPECT_TRUE(app_sorting->GetPageOrdinal(app_id).Equals(kPageOrdinal)); |
310 } | 435 } |
311 | 436 |
312 void InitSyncService() { | 437 void InitSyncService() { |
313 ExtensionSyncService* sync_service = ExtensionSyncService::Get(profile()); | 438 ExtensionSyncService* sync_service = ExtensionSyncService::Get(profile()); |
314 sync_service->MergeDataAndStartSyncing( | 439 sync_service->MergeDataAndStartSyncing( |
315 syncer::APPS, | 440 syncer::APPS, |
316 syncer::SyncDataList(), | 441 syncer::SyncDataList(), |
317 scoped_ptr<syncer::SyncChangeProcessor>( | 442 scoped_ptr<syncer::SyncChangeProcessor>( |
318 new syncer::SyncChangeProcessorWrapperForTest( | 443 new syncer::SyncChangeProcessorWrapperForTest( |
319 &mock_sync_processor_)), | 444 &mock_sync_processor_)), |
(...skipping 15 matching lines...) Expand all Loading... |
335 } | 460 } |
336 | 461 |
337 void VerifySyncChange(const AppSyncData* sync_change, bool expect_enabled) { | 462 void VerifySyncChange(const AppSyncData* sync_change, bool expect_enabled) { |
338 ASSERT_TRUE(sync_change); | 463 ASSERT_TRUE(sync_change); |
339 EXPECT_TRUE(sync_change->page_ordinal().IsValid()); | 464 EXPECT_TRUE(sync_change->page_ordinal().IsValid()); |
340 EXPECT_TRUE(sync_change->app_launch_ordinal().IsValid()); | 465 EXPECT_TRUE(sync_change->app_launch_ordinal().IsValid()); |
341 EXPECT_FALSE(sync_change->uninstalled()); | 466 EXPECT_FALSE(sync_change->uninstalled()); |
342 EXPECT_EQ(expect_enabled, sync_change->extension_sync_data().enabled()); | 467 EXPECT_EQ(expect_enabled, sync_change->extension_sync_data().enabled()); |
343 } | 468 } |
344 | 469 |
| 470 void TestInstallEvent(bool close_app) { |
| 471 ExtensionTestMessageListener first_msg_listener(false); |
| 472 const Extension* app = InstallAndLaunchEphemeralApp(kDispatchEventTestApp); |
| 473 ASSERT_TRUE(app); |
| 474 |
| 475 // When an ephemeral app is first added, it should not receive the |
| 476 // onInstalled event, hence the first message received from the test should |
| 477 // be "launched" and not "installed". |
| 478 ASSERT_TRUE(first_msg_listener.WaitUntilSatisfied()); |
| 479 EXPECT_EQ(std::string("launched"), first_msg_listener.message()); |
| 480 |
| 481 if (close_app) |
| 482 CloseAppWaitForUnload(app->id()); |
| 483 |
| 484 // When installed permanently, the app should receive the onInstalled event. |
| 485 ExtensionTestMessageListener install_listener("installed", false); |
| 486 PromoteEphemeralApp(app); |
| 487 ASSERT_TRUE(install_listener.WaitUntilSatisfied()); |
| 488 } |
| 489 |
| 490 private: |
345 syncer::FakeSyncChangeProcessor mock_sync_processor_; | 491 syncer::FakeSyncChangeProcessor mock_sync_processor_; |
346 }; | 492 }; |
347 | 493 |
348 // Verify that ephemeral apps can be launched and receive system events when | 494 // Verify that ephemeral apps can be launched and receive system events when |
349 // they are running. Once they are inactive they should not receive system | 495 // they are running. Once they are inactive they should not receive system |
350 // events. | 496 // events. |
351 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, EventDispatchWhenLaunched) { | 497 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, EventDispatchWhenLaunched) { |
352 const Extension* extension = | 498 const Extension* extension = |
353 InstallAndLaunchEphemeralApp(kDispatchEventTestApp); | 499 InstallAndLaunchEphemeralApp(kDispatchEventTestApp); |
354 ASSERT_TRUE(extension); | 500 ASSERT_TRUE(extension); |
355 | 501 |
356 // Send a fake alarm event to the app and verify that a response is | 502 // Send a fake alarm event to the app and verify that a response is |
357 // received. | 503 // received. |
358 EventRouter* event_router = EventRouter::Get(profile()); | 504 EventRouter* event_router = EventRouter::Get(profile()); |
359 ASSERT_TRUE(event_router); | 505 ASSERT_TRUE(event_router); |
360 | 506 |
361 ExtensionTestMessageListener alarm_received_listener("alarm_received", false); | 507 ExtensionTestMessageListener alarm_received_listener("alarm_received", false); |
362 DispatchAlarmEvent(event_router, extension->id()); | 508 DispatchAlarmEvent(event_router, extension->id()); |
363 ASSERT_TRUE(alarm_received_listener.WaitUntilSatisfied()); | 509 ASSERT_TRUE(alarm_received_listener.WaitUntilSatisfied()); |
364 | 510 |
365 CloseApp(extension->id()); | 511 CloseAppWaitForUnload(extension->id()); |
366 | |
367 // The app needs to be launched once in order to have the onAlarm() event | |
368 // registered. | |
369 ASSERT_TRUE(event_router->ExtensionHasEventListener( | |
370 extension->id(), alarms::OnAlarm::kEventName)); | |
371 | 512 |
372 // Dispatch the alarm event again and verify that the event page did not get | 513 // Dispatch the alarm event again and verify that the event page did not get |
373 // loaded for the app. | 514 // loaded for the app. |
374 DispatchAlarmEvent(event_router, extension->id()); | 515 DispatchAlarmEvent(event_router, extension->id()); |
375 VerifyAppNotLoaded(extension->id()); | 516 VerifyAppNotLoaded(extension->id()); |
376 } | 517 } |
377 | 518 |
378 // Verify that ephemeral apps will receive messages while they are running. | 519 // Verify that ephemeral apps will receive messages while they are running. |
379 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, ReceiveMessagesWhenLaunched) { | 520 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, ReceiveMessagesWhenLaunched) { |
380 const Extension* receiver = | 521 const Extension* receiver = |
381 InstallAndLaunchEphemeralApp(kMessagingReceiverApp); | 522 InstallAndLaunchEphemeralApp(kMessagingReceiverApp); |
382 ASSERT_TRUE(receiver); | 523 ASSERT_TRUE(receiver); |
383 | 524 |
384 // Verify that messages are received while the app is running. | 525 // Verify that messages are received while the app is running. |
385 ExtensionApiTest::ResultCatcher result_catcher; | 526 ExtensionApiTest::ResultCatcher result_catcher; |
386 LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_success", | 527 LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_success", |
387 "Launched"); | 528 "Launched"); |
388 EXPECT_TRUE(result_catcher.GetNextResult()); | 529 EXPECT_TRUE(result_catcher.GetNextResult()); |
389 | 530 |
390 CloseApp(receiver->id()); | 531 CloseAppWaitForUnload(receiver->id()); |
391 | 532 |
392 // Verify that messages are not received while the app is inactive. | 533 // Verify that messages are not received while the app is inactive. |
393 LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_fail", "Launched"); | 534 LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_fail", "Launched"); |
394 EXPECT_TRUE(result_catcher.GetNextResult()); | 535 EXPECT_TRUE(result_catcher.GetNextResult()); |
395 } | 536 } |
396 | 537 |
| 538 // Verifies that the chrome.runtime.onInstalled() event is received by a running |
| 539 // ephemeral app only when it is promoted. |
| 540 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
| 541 InstallEventReceivedWhileRunning) { |
| 542 TestInstallEvent(false /* close app */); |
| 543 } |
| 544 |
| 545 // Verifies that when an idle ephemeral app is promoted, it will be loaded to |
| 546 // receive the chrome.runtime.onInstalled() event. |
| 547 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, InstallEventReceivedWhileIdle) { |
| 548 TestInstallEvent(true /* close app */); |
| 549 } |
| 550 |
| 551 // Verifies that the chrome.runtime.onRestarted() event is received by an |
| 552 // ephemeral app. |
| 553 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, RestartEventReceived) { |
| 554 const Extension* app = InstallAndLaunchEphemeralApp(kDispatchEventTestApp); |
| 555 ASSERT_TRUE(app); |
| 556 CloseAppWaitForUnload(app->id()); |
| 557 |
| 558 // Fake ephemeral app running before restart. |
| 559 ExtensionSystem::Get(profile())->extension_service()->EnableExtension( |
| 560 app->id()); |
| 561 ASSERT_TRUE(ExtensionRegistry::Get(profile())->enabled_extensions().Contains( |
| 562 app->id())); |
| 563 ExtensionPrefs::Get(profile())->SetExtensionRunning(app->id(), true); |
| 564 |
| 565 ExtensionTestMessageListener restart_listener("restarted", false); |
| 566 apps::AppRestoreService::Get(profile())->HandleStartup(true); |
| 567 EXPECT_TRUE(restart_listener.WaitUntilSatisfied()); |
| 568 } |
| 569 |
397 // Verify that an updated ephemeral app will still have its ephemeral flag | 570 // Verify that an updated ephemeral app will still have its ephemeral flag |
398 // enabled. | 571 // enabled. |
399 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, UpdateEphemeralApp) { | 572 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, UpdateEphemeralApp) { |
400 const Extension* app_v1 = InstallEphemeralApp(kMessagingReceiverApp); | 573 const Extension* app_v1 = InstallAndLaunchEphemeralApp(kMessagingReceiverApp); |
401 ASSERT_TRUE(app_v1); | 574 ASSERT_TRUE(app_v1); |
| 575 CloseAppWaitForUnload(app_v1->id()); |
| 576 VerifyInactiveEphemeralApp(app_v1->id()); |
| 577 |
402 std::string app_id = app_v1->id(); | 578 std::string app_id = app_v1->id(); |
403 base::Version app_original_version = *app_v1->version(); | 579 base::Version app_original_version = *app_v1->version(); |
404 app_v1 = NULL; // The extension object will be destroyed during update. | 580 app_v1 = NULL; // The extension object will be destroyed during update. |
405 | 581 |
406 // Update to version 2 of the app. | 582 // Update to version 2 of the app. |
407 InstallObserver installed_observer(profile()); | 583 InstallObserver installed_observer(profile()); |
408 const Extension* app_v2 = UpdateEphemeralApp( | 584 const Extension* app_v2 = |
409 app_id, GetTestPath(kMessagingReceiverAppV2), | 585 UpdateEphemeralApp(app_id, |
410 GetTestPath(kMessagingReceiverApp).ReplaceExtension( | 586 GetTestPath(kMessagingReceiverAppV2), |
411 FILE_PATH_LITERAL(".pem"))); | 587 GetTestPath(kMessagingReceiverApp) |
| 588 .ReplaceExtension(FILE_PATH_LITERAL(".pem"))); |
412 | 589 |
413 // Check the notification parameters. | 590 // Check the notification parameters. |
414 const InstallObserver::InstallParameters& params = installed_observer.Last(); | 591 const InstallObserver::InstallParameters& params = installed_observer.Last(); |
415 EXPECT_EQ(app_id, params.id); | 592 EXPECT_EQ(app_id, params.id); |
416 EXPECT_TRUE(params.is_update); | 593 EXPECT_TRUE(params.is_update); |
417 EXPECT_FALSE(params.from_ephemeral); | 594 EXPECT_FALSE(params.from_ephemeral); |
418 | 595 |
419 // The ephemeral flag should still be enabled. | 596 // The ephemeral flag should still be set. |
420 ASSERT_TRUE(app_v2); | 597 ASSERT_TRUE(app_v2); |
421 EXPECT_TRUE(app_v2->version()->CompareTo(app_original_version) > 0); | 598 EXPECT_GT(app_v2->version()->CompareTo(app_original_version), 0); |
422 EXPECT_TRUE(extensions::util::IsEphemeralApp(app_v2->id(), profile())); | 599 EXPECT_TRUE(extensions::util::IsEphemeralApp(app_v2->id(), profile())); |
| 600 |
| 601 // The app should still be disabled in extension system. |
| 602 VerifyInactiveEphemeralApp(app_id); |
423 } | 603 } |
424 | 604 |
425 // Verify that if notifications have been disabled for an ephemeral app, it will | 605 // Verify that if notifications have been disabled for an ephemeral app, it will |
426 // remain disabled even after being evicted from the cache. | 606 // remain disabled even after being evicted from the cache. |
427 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, StickyNotificationSettings) { | 607 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, StickyNotificationSettings) { |
428 const Extension* app = InstallEphemeralApp(kNotificationsTestApp); | 608 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
429 ASSERT_TRUE(app); | 609 ASSERT_TRUE(app); |
430 | 610 |
431 // Disable notifications for this app. | 611 // Disable notifications for this app. |
432 DesktopNotificationService* notification_service = | 612 DesktopNotificationService* notification_service = |
433 DesktopNotificationServiceFactory::GetForProfile(profile()); | 613 DesktopNotificationServiceFactory::GetForProfile(profile()); |
434 ASSERT_TRUE(notification_service); | 614 ASSERT_TRUE(notification_service); |
435 | 615 |
436 message_center::NotifierId notifier_id( | 616 message_center::NotifierId notifier_id( |
437 message_center::NotifierId::APPLICATION, app->id()); | 617 message_center::NotifierId::APPLICATION, app->id()); |
438 EXPECT_TRUE(notification_service->IsNotifierEnabled(notifier_id)); | 618 EXPECT_TRUE(notification_service->IsNotifierEnabled(notifier_id)); |
439 notification_service->SetNotifierEnabled(notifier_id, false); | 619 notification_service->SetNotifierEnabled(notifier_id, false); |
440 EXPECT_FALSE(notification_service->IsNotifierEnabled(notifier_id)); | 620 EXPECT_FALSE(notification_service->IsNotifierEnabled(notifier_id)); |
441 | 621 |
442 // Remove the app. | 622 // Remove the app. |
| 623 CloseAppWaitForUnload(app->id()); |
443 EvictApp(app->id()); | 624 EvictApp(app->id()); |
444 | 625 |
445 // Reinstall the ephemeral app and verify that notifications remain disabled. | 626 // Reinstall the ephemeral app and verify that notifications remain disabled. |
446 app = InstallEphemeralApp(kNotificationsTestApp); | 627 app = InstallEphemeralApp(kNotificationsTestApp); |
447 ASSERT_TRUE(app); | 628 ASSERT_TRUE(app); |
448 message_center::NotifierId reinstalled_notifier_id( | 629 message_center::NotifierId reinstalled_notifier_id( |
449 message_center::NotifierId::APPLICATION, app->id()); | 630 message_center::NotifierId::APPLICATION, app->id()); |
450 EXPECT_FALSE(notification_service->IsNotifierEnabled( | 631 EXPECT_FALSE(notification_service->IsNotifierEnabled( |
451 reinstalled_notifier_id)); | 632 reinstalled_notifier_id)); |
452 } | 633 } |
453 | 634 |
454 // Verify that only running ephemeral apps will appear in the Notification | 635 // Verify that only running ephemeral apps will appear in the Notification |
455 // Settings UI. Inactive, cached ephemeral apps should not appear. | 636 // Settings UI. Inactive, cached ephemeral apps should not appear. |
456 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, | 637 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
457 IncludeRunningEphemeralAppsInNotifiers) { | 638 IncludeRunningEphemeralAppsInNotifiers) { |
458 message_center::NotifierSettingsProvider* settings_provider = | 639 message_center::NotifierSettingsProvider* settings_provider = |
459 message_center::MessageCenter::Get()->GetNotifierSettingsProvider(); | 640 message_center::MessageCenter::Get()->GetNotifierSettingsProvider(); |
460 // TODO(tmdiep): Remove once notifications settings are supported across | 641 DCHECK(settings_provider); |
461 // all platforms. This test will fail for Linux GTK. | |
462 if (!settings_provider) | |
463 return; | |
464 | 642 |
465 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); | 643 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
466 ASSERT_TRUE(app); | 644 ASSERT_TRUE(app); |
467 message_center::NotifierId notifier_id( | 645 message_center::NotifierId notifier_id( |
468 message_center::NotifierId::APPLICATION, app->id()); | 646 message_center::NotifierId::APPLICATION, app->id()); |
469 | 647 |
470 // Since the ephemeral app is running, it should be included in the list | 648 // Since the ephemeral app is running, it should be included in the list |
471 // of notifiers to show in the UI. | 649 // of notifiers to show in the UI. |
472 NotifierList notifiers; | 650 NotifierList notifiers; |
473 STLElementDeleter<NotifierList> notifier_deleter(¬ifiers); | 651 STLElementDeleter<NotifierList> notifier_deleter(¬ifiers); |
474 | 652 |
475 settings_provider->GetNotifierList(¬ifiers); | 653 settings_provider->GetNotifierList(¬ifiers); |
476 EXPECT_TRUE(IsNotifierInList(notifier_id, notifiers)); | 654 EXPECT_TRUE(IsNotifierInList(notifier_id, notifiers)); |
477 STLDeleteElements(¬ifiers); | 655 STLDeleteElements(¬ifiers); |
478 | 656 |
479 // Close the ephemeral app. | 657 // Close the ephemeral app. |
480 CloseApp(app->id()); | 658 CloseAppWaitForUnload(app->id()); |
481 | 659 |
482 // Inactive ephemeral apps should not be included in the list of notifiers to | 660 // Inactive ephemeral apps should not be included in the list of notifiers to |
483 // show in the UI. | 661 // show in the UI. |
484 settings_provider->GetNotifierList(¬ifiers); | 662 settings_provider->GetNotifierList(¬ifiers); |
485 EXPECT_FALSE(IsNotifierInList(notifier_id, notifiers)); | 663 EXPECT_FALSE(IsNotifierInList(notifier_id, notifiers)); |
486 } | 664 } |
487 | 665 |
488 // Verify that ephemeral apps will have no ability to retain file entries after | 666 // Verify that ephemeral apps will have no ability to retain file entries after |
489 // close. Normal retainEntry behavior for installed apps is tested in | 667 // close. Normal retainEntry behavior for installed apps is tested in |
490 // FileSystemApiTest. | 668 // FileSystemApiTest. |
(...skipping 22 matching lines...) Expand all Loading... |
513 // flushed. | 691 // flushed. |
514 std::vector<apps::SavedFileEntry> file_entries = | 692 std::vector<apps::SavedFileEntry> file_entries = |
515 apps::SavedFilesService::Get(profile()) | 693 apps::SavedFilesService::Get(profile()) |
516 ->GetAllFileEntries(app->id()); | 694 ->GetAllFileEntries(app->id()); |
517 EXPECT_TRUE(file_entries.empty()); | 695 EXPECT_TRUE(file_entries.empty()); |
518 | 696 |
519 // The second test verifies that the file cannot be reopened. | 697 // The second test verifies that the file cannot be reopened. |
520 ASSERT_TRUE(LaunchAppAndRunTest(app, "RestoreRetainedFile")) << message_; | 698 ASSERT_TRUE(LaunchAppAndRunTest(app, "RestoreRetainedFile")) << message_; |
521 } | 699 } |
522 | 700 |
523 // Checks the process of installing and then promoting an ephemeral app. | 701 // Checks the process of launching an ephemeral app and then promoting the app |
524 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteEphemeralApp) { | 702 // while it is running. |
| 703 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteAppWhileRunning) { |
525 InitSyncService(); | 704 InitSyncService(); |
526 | 705 |
527 const Extension* app = InstallEphemeralApp(kNotificationsTestApp); | 706 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
528 ASSERT_TRUE(app); | 707 ASSERT_TRUE(app); |
529 | 708 |
530 // Ephemeral apps should not be synced. | 709 PromoteEphemeralAppAndVerify(app, ExtensionRegistry::ENABLED); |
531 scoped_ptr<AppSyncData> sync_change = GetFirstSyncChangeForApp(app->id()); | |
532 EXPECT_FALSE(sync_change.get()); | |
533 | 710 |
534 // Promote the app to a regular installed app. | 711 // Ensure that the app is not unloaded and disabled after it is closed. |
535 InstallObserver installed_observer(profile()); | 712 CloseApp(app->id()); |
536 PromoteEphemeralApp(app); | |
537 VerifyPromotedApp(app->id(), ExtensionRegistry::ENABLED); | 713 VerifyPromotedApp(app->id(), ExtensionRegistry::ENABLED); |
538 | |
539 // Check the notification parameters. | |
540 const InstallObserver::InstallParameters& params = installed_observer.Last(); | |
541 EXPECT_EQ(app->id(), params.id); | |
542 EXPECT_TRUE(params.is_update); | |
543 EXPECT_TRUE(params.from_ephemeral); | |
544 | |
545 // The installation should now be synced. | |
546 sync_change = GetFirstSyncChangeForApp(app->id()); | |
547 VerifySyncChange(sync_change.get(), true); | |
548 } | 714 } |
549 | 715 |
550 // Verifies that promoting an ephemeral app will enable it. | 716 // Checks the process of launching an ephemeral app and then promoting the app |
551 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteEphemeralAppAndEnable) { | 717 // while it is idle. |
| 718 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteAppWhileIdle) { |
552 InitSyncService(); | 719 InitSyncService(); |
553 | 720 |
554 const Extension* app = InstallEphemeralApp(kNotificationsTestApp); | 721 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
555 ASSERT_TRUE(app); | 722 ASSERT_TRUE(app); |
| 723 CloseAppWaitForUnload(app->id()); |
| 724 VerifyInactiveEphemeralApp(app->id()); |
556 | 725 |
557 // Disable the ephemeral app due to a permissions increase. This also involves | 726 PromoteEphemeralAppAndVerify(app, ExtensionRegistry::ENABLED); |
558 // setting the DidExtensionEscalatePermissions flag. | 727 } |
559 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); | |
560 prefs->SetDidExtensionEscalatePermissions(app, true); | |
561 ExtensionService* service = | |
562 ExtensionSystem::Get(profile())->extension_service(); | |
563 service->DisableExtension(app->id(), Extension::DISABLE_PERMISSIONS_INCREASE); | |
564 ASSERT_TRUE(ExtensionRegistry::Get(profile())-> | |
565 GetExtensionById(app->id(), ExtensionRegistry::DISABLED)); | |
566 | 728 |
567 // Promote to a regular installed app. It should be enabled. | 729 // Verifies that promoting an ephemeral app that was disabled due to a |
568 PromoteEphemeralApp(app); | 730 // permissions increase will enable it. |
569 VerifyPromotedApp(app->id(), ExtensionRegistry::ENABLED); | 731 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteAppAndGrantPermissions) { |
570 EXPECT_FALSE(prefs->DidExtensionEscalatePermissions(app->id())); | 732 InitSyncService(); |
571 | 733 |
572 scoped_ptr<AppSyncData> sync_change = GetFirstSyncChangeForApp(app->id()); | 734 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
573 VerifySyncChange(sync_change.get(), true); | 735 ASSERT_TRUE(app); |
| 736 CloseAppWaitForUnload(app->id()); |
| 737 DisableEphemeralApp(app, Extension::DISABLE_PERMISSIONS_INCREASE); |
| 738 |
| 739 PromoteEphemeralAppAndVerify(app, ExtensionRegistry::ENABLED); |
| 740 EXPECT_FALSE(ExtensionPrefs::Get(profile()) |
| 741 ->DidExtensionEscalatePermissions(app->id())); |
574 } | 742 } |
575 | 743 |
576 // Verifies that promoting an ephemeral app that has unsupported requirements | 744 // Verifies that promoting an ephemeral app that has unsupported requirements |
577 // will not enable it. | 745 // will not enable it. |
578 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, | 746 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
579 PromoteUnsupportedEphemeralApp) { | 747 PromoteUnsupportedEphemeralApp) { |
580 InitSyncService(); | 748 InitSyncService(); |
581 | 749 |
582 const Extension* app = InstallEphemeralApp(kNotificationsTestApp); | 750 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
583 ASSERT_TRUE(app); | 751 ASSERT_TRUE(app); |
| 752 CloseAppWaitForUnload(app->id()); |
| 753 DisableEphemeralApp(app, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); |
584 | 754 |
585 // Disable the ephemeral app. | 755 // When promoted to a regular installed app, it should remain disabled. |
| 756 PromoteEphemeralAppAndVerify(app, ExtensionRegistry::DISABLED); |
| 757 } |
| 758 |
| 759 // Verifies that promoting an ephemeral app that is blacklisted will not enable |
| 760 // it. |
| 761 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
| 762 PromoteBlacklistedEphemeralApp) { |
| 763 InitSyncService(); |
| 764 |
| 765 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
| 766 ASSERT_TRUE(app); |
| 767 CloseAppWaitForUnload(app->id()); |
| 768 |
586 ExtensionService* service = | 769 ExtensionService* service = |
587 ExtensionSystem::Get(profile())->extension_service(); | 770 ExtensionSystem::Get(profile())->extension_service(); |
588 service->DisableExtension( | 771 service->BlacklistExtensionForTest(app->id()); |
589 app->id(), Extension::DISABLE_UNSUPPORTED_REQUIREMENT); | 772 ASSERT_TRUE( |
590 ASSERT_TRUE(ExtensionRegistry::Get(profile())-> | 773 ExtensionRegistry::Get(profile())->blacklisted_extensions().Contains( |
591 GetExtensionById(app->id(), ExtensionRegistry::DISABLED)); | 774 app->id())); |
592 | 775 |
593 // Promote to a regular installed app. It should remain disabled. | 776 // When promoted to a regular installed app, it should remain blacklisted. |
594 PromoteEphemeralApp(app); | 777 PromoteEphemeralAppAndVerify(app, ExtensionRegistry::BLACKLISTED); |
595 VerifyPromotedApp(app->id(), ExtensionRegistry::DISABLED); | |
596 | 778 |
| 779 // The app should be synced, but disabled. |
597 scoped_ptr<AppSyncData> sync_change = GetFirstSyncChangeForApp(app->id()); | 780 scoped_ptr<AppSyncData> sync_change = GetFirstSyncChangeForApp(app->id()); |
598 VerifySyncChange(sync_change.get(), false); | 781 VerifySyncChange(sync_change.get(), false); |
599 } | 782 } |
600 | 783 |
601 // Checks the process of promoting an ephemeral app from sync. | 784 // Checks the process of promoting an ephemeral app from sync while the app is |
602 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteEphemeralAppFromSync) { | 785 // running. |
| 786 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
| 787 PromoteAppFromSyncWhileRunning) { |
603 InitSyncService(); | 788 InitSyncService(); |
604 | 789 |
605 const Extension* app = InstallEphemeralApp(kNotificationsTestApp); | 790 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
606 ASSERT_TRUE(app); | 791 ASSERT_TRUE(app); |
607 std::string app_id = app->id(); | |
608 | 792 |
609 // Simulate an install from sync. | 793 PromoteEphemeralAppFromSyncAndVerify(app, true, ExtensionRegistry::ENABLED); |
610 const syncer::StringOrdinal kAppLaunchOrdinal("x"); | |
611 const syncer::StringOrdinal kPageOrdinal("y"); | |
612 AppSyncData app_sync_data( | |
613 *app, | |
614 true /* enabled */, | |
615 false /* incognito enabled */, | |
616 false /* remote install */, | |
617 kAppLaunchOrdinal, | |
618 kPageOrdinal, | |
619 extensions::LAUNCH_TYPE_REGULAR); | |
620 | 794 |
621 ExtensionSyncService* sync_service = ExtensionSyncService::Get(profile()); | 795 // Ensure that the app is not unloaded and disabled after it is closed. |
622 sync_service->ProcessAppSyncData(app_sync_data); | 796 CloseApp(app->id()); |
| 797 VerifyPromotedApp(app->id(), ExtensionRegistry::ENABLED); |
| 798 } |
623 | 799 |
624 // Verify the installation. | 800 // Checks the process of promoting an ephemeral app from sync while the app is |
625 VerifyPromotedApp(app_id, ExtensionRegistry::ENABLED); | 801 // idle. |
| 802 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteAppFromSyncWhileIdle) { |
| 803 InitSyncService(); |
626 | 804 |
627 // The sort ordinals from sync should not be overridden. | 805 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
628 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); | 806 ASSERT_TRUE(app); |
629 extensions::AppSorting* app_sorting = prefs->app_sorting(); | 807 CloseAppWaitForUnload(app->id()); |
630 EXPECT_TRUE(app_sorting->GetAppLaunchOrdinal(app_id).Equals( | 808 VerifyInactiveEphemeralApp(app->id()); |
631 kAppLaunchOrdinal)); | 809 |
632 EXPECT_TRUE(app_sorting->GetPageOrdinal(app_id).Equals(kPageOrdinal)); | 810 PromoteEphemeralAppFromSyncAndVerify(app, true, ExtensionRegistry::ENABLED); |
| 811 } |
| 812 |
| 813 // Checks the process of promoting an ephemeral app from sync, where the app |
| 814 // from sync is disabled, and the ephemeral app is running. |
| 815 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
| 816 PromoteDisabledAppFromSyncWhileRunning) { |
| 817 InitSyncService(); |
| 818 |
| 819 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
| 820 ASSERT_TRUE(app); |
| 821 |
| 822 PromoteEphemeralAppFromSyncAndVerify(app, false, ExtensionRegistry::DISABLED); |
| 823 } |
| 824 |
| 825 // Checks the process of promoting an ephemeral app from sync, where the app |
| 826 // from sync is disabled, and the ephemeral app is idle. |
| 827 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
| 828 PromoteDisabledAppFromSyncWhileIdle) { |
| 829 InitSyncService(); |
| 830 |
| 831 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
| 832 ASSERT_TRUE(app); |
| 833 CloseAppWaitForUnload(app->id()); |
| 834 VerifyInactiveEphemeralApp(app->id()); |
| 835 |
| 836 PromoteEphemeralAppFromSyncAndVerify(app, false, ExtensionRegistry::DISABLED); |
633 } | 837 } |
634 | 838 |
635 // In most cases, ExtensionService::PromoteEphemeralApp() will be called to | 839 // In most cases, ExtensionService::PromoteEphemeralApp() will be called to |
636 // permanently install an ephemeral app. However, there may be cases where an | 840 // permanently install an ephemeral app. However, there may be cases where an |
637 // install occurs through the usual route of installing from the Web Store (due | 841 // install occurs through the usual route of installing from the Web Store (due |
638 // to race conditions). Ensure that the app is still installed correctly. | 842 // to race conditions). Ensure that the app is still installed correctly. |
639 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, | 843 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
640 ReplaceEphemeralAppWithInstalledApp) { | 844 ReplaceEphemeralAppWithInstalledApp) { |
641 const Extension* app = InstallEphemeralApp(kNotificationsTestApp); | 845 InitSyncService(); |
| 846 |
| 847 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
642 ASSERT_TRUE(app); | 848 ASSERT_TRUE(app); |
| 849 CloseAppWaitForUnload(app->id()); |
643 std::string app_id = app->id(); | 850 std::string app_id = app->id(); |
644 app = NULL; | 851 app = NULL; |
645 | 852 |
646 InstallObserver installed_observer(profile()); | 853 InstallObserver installed_observer(profile()); |
647 ReplaceEphemeralApp(app_id, kNotificationsTestApp); | 854 ReplaceEphemeralApp(app_id, kNotificationsTestApp, 1); |
648 VerifyPromotedApp(app_id, ExtensionRegistry::ENABLED); | 855 VerifyPromotedApp(app_id, ExtensionRegistry::ENABLED); |
649 | 856 |
650 // Check the notification parameters. | 857 // Check the notification parameters. |
651 const InstallObserver::InstallParameters& params = installed_observer.Last(); | 858 const InstallObserver::InstallParameters& params = installed_observer.Last(); |
652 EXPECT_EQ(app_id, params.id); | 859 EXPECT_EQ(app_id, params.id); |
653 EXPECT_TRUE(params.is_update); | 860 EXPECT_TRUE(params.is_update); |
654 EXPECT_TRUE(params.from_ephemeral); | 861 EXPECT_TRUE(params.from_ephemeral); |
655 } | 862 } |
656 | 863 |
657 // This is similar to ReplaceEphemeralAppWithInstalledApp, but installs will | 864 // This is similar to ReplaceEphemeralAppWithInstalledApp, but installs will |
658 // be delayed until the app is idle. | 865 // be delayed until the app is idle. |
659 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, | 866 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
660 ReplaceEphemeralAppWithDelayedInstalledApp) { | 867 ReplaceEphemeralAppWithDelayedInstalledApp) { |
| 868 InitSyncService(); |
| 869 |
661 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); | 870 const Extension* app = InstallAndLaunchEphemeralApp(kNotificationsTestApp); |
662 ASSERT_TRUE(app); | 871 ASSERT_TRUE(app); |
663 std::string app_id = app->id(); | 872 std::string app_id = app->id(); |
664 app = NULL; | 873 app = NULL; |
665 | 874 |
666 // Initiate install. | 875 // Initiate install. |
667 ReplaceEphemeralApp(app_id, kNotificationsTestApp); | 876 ReplaceEphemeralApp(app_id, kNotificationsTestApp, 0); |
668 | 877 |
669 // The delayed installation will occur when the ephemeral app is closed. | 878 // The delayed installation will occur when the ephemeral app is closed. |
670 content::WindowedNotificationObserver installed_signal( | 879 content::WindowedNotificationObserver installed_signal( |
671 chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED, | 880 chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED, |
672 content::Source<Profile>(profile())); | 881 content::Source<Profile>(profile())); |
673 InstallObserver installed_observer(profile()); | 882 InstallObserver installed_observer(profile()); |
674 CloseApp(app_id); | 883 CloseAppWaitForUnload(app_id); |
675 installed_signal.Wait(); | 884 installed_signal.Wait(); |
676 VerifyPromotedApp(app_id, ExtensionRegistry::ENABLED); | 885 VerifyPromotedApp(app_id, ExtensionRegistry::ENABLED); |
677 | 886 |
678 // Check the notification parameters. | 887 // Check the notification parameters. |
679 const InstallObserver::InstallParameters& params = installed_observer.Last(); | 888 const InstallObserver::InstallParameters& params = installed_observer.Last(); |
680 EXPECT_EQ(app_id, params.id); | 889 EXPECT_EQ(app_id, params.id); |
681 EXPECT_TRUE(params.is_update); | 890 EXPECT_TRUE(params.is_update); |
682 EXPECT_TRUE(params.from_ephemeral); | 891 EXPECT_TRUE(params.from_ephemeral); |
683 } | 892 } |
684 | 893 |
| 894 // Verifies that an installed app cannot turn into an ephemeral app as result of |
| 895 // race conditions, i.e. an ephemeral app can be promoted to an installed app, |
| 896 // but not vice versa. |
| 897 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
| 898 ReplaceInstalledAppWithEphemeralApp) { |
| 899 const Extension* app = InstallPlatformApp(kNotificationsTestApp); |
| 900 ASSERT_TRUE(app); |
| 901 std::string app_id = app->id(); |
| 902 app = NULL; |
| 903 |
| 904 EXPECT_FALSE(extensions::util::IsEphemeralApp(app_id, profile())); |
| 905 app = |
| 906 InstallEphemeralAppWithSourceAndFlags(GetTestPath(kNotificationsTestApp), |
| 907 0, |
| 908 Manifest::INTERNAL, |
| 909 Extension::NO_FLAGS); |
| 910 EXPECT_FALSE(extensions::util::IsEphemeralApp(app_id, profile())); |
| 911 } |
| 912 |
685 // Ephemerality was previously encoded by the Extension::IS_EPHEMERAL creation | 913 // Ephemerality was previously encoded by the Extension::IS_EPHEMERAL creation |
686 // flag. This was changed to an "ephemeral_app" property. Check that the prefs | 914 // flag. This was changed to an "ephemeral_app" property. Check that the prefs |
687 // are handled correctly. | 915 // are handled correctly. |
688 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, | 916 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, |
689 ExtensionPrefBackcompatibility) { | 917 ExtensionPrefBackcompatibility) { |
690 // Ensure that apps with the old prefs are recognized as ephemeral. | 918 // Ensure that apps with the old prefs are recognized as ephemeral. |
691 const Extension* app = | 919 const Extension* app = |
692 InstallExtensionWithSourceAndFlags(GetTestPath(kNotificationsTestApp), | 920 InstallExtensionWithSourceAndFlags(GetTestPath(kNotificationsTestApp), |
693 1, | 921 1, |
694 Manifest::INTERNAL, | 922 Manifest::INTERNAL, |
695 Extension::IS_EPHEMERAL); | 923 Extension::IS_EPHEMERAL); |
696 ASSERT_TRUE(app); | 924 ASSERT_TRUE(app); |
697 EXPECT_TRUE(extensions::util::IsEphemeralApp(app->id(), profile())); | 925 EXPECT_TRUE(extensions::util::IsEphemeralApp(app->id(), profile())); |
698 | 926 |
699 // Ensure that when the app is promoted to an installed app, the bit in the | 927 // Ensure that when the app is promoted to an installed app, the bit in the |
700 // creation flags is cleared. | 928 // creation flags is cleared. |
701 PromoteEphemeralApp(app); | 929 PromoteEphemeralApp(app); |
702 EXPECT_FALSE(extensions::util::IsEphemeralApp(app->id(), profile())); | 930 EXPECT_FALSE(extensions::util::IsEphemeralApp(app->id(), profile())); |
703 | 931 |
704 int creation_flags = | 932 int creation_flags = |
705 ExtensionPrefs::Get(profile())->GetCreationFlags(app->id()); | 933 ExtensionPrefs::Get(profile())->GetCreationFlags(app->id()); |
706 EXPECT_EQ(0, creation_flags & Extension::IS_EPHEMERAL); | 934 EXPECT_EQ(0, creation_flags & Extension::IS_EPHEMERAL); |
707 } | 935 } |
OLD | NEW |