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

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: Rebase Created 6 years, 4 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 23 matching lines...) Expand all
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
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
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
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(&notifiers); 673 STLElementDeleter<NotifierList> notifier_deleter(&notifiers);
500 674
501 settings_provider->GetNotifierList(&notifiers); 675 settings_provider->GetNotifierList(&notifiers);
502 EXPECT_TRUE(IsNotifierInList(notifier_id, notifiers)); 676 EXPECT_TRUE(IsNotifierInList(notifier_id, notifiers));
503 STLDeleteElements(&notifiers); 677 STLDeleteElements(&notifiers);
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(&notifiers); 684 settings_provider->GetNotifierList(&notifiers);
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698