Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: chrome/browser/apps/ephemeral_app_browsertest.cc

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

Powered by Google App Engine
This is Rietveld 408576698