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