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 |