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