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

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

Issue 297263003: Optimize promotion of ephemeral apps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed review comments and added more tests Created 6 years, 7 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"
6
7 #include <vector>
8
5 #include "apps/saved_files_service.h" 9 #include "apps/saved_files_service.h"
6 #include "base/files/scoped_temp_dir.h" 10 #include "base/files/scoped_temp_dir.h"
7 #include "base/stl_util.h" 11 #include "base/stl_util.h"
8 #include "chrome/browser/apps/app_browsertest_util.h" 12 #include "chrome/browser/apps/app_browsertest_util.h"
9 #include "chrome/browser/apps/ephemeral_app_service.h" 13 #include "chrome/browser/apps/ephemeral_app_service.h"
10 #include "chrome/browser/extensions/api/file_system/file_system_api.h" 14 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
15 #include "chrome/browser/extensions/app_sync_data.h"
11 #include "chrome/browser/extensions/extension_service.h" 16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/extensions/extension_sync_service.h"
12 #include "chrome/browser/extensions/extension_test_message_listener.h" 18 #include "chrome/browser/extensions/extension_test_message_listener.h"
13 #include "chrome/browser/extensions/extension_util.h" 19 #include "chrome/browser/extensions/extension_util.h"
14 #include "chrome/browser/notifications/desktop_notification_service.h" 20 #include "chrome/browser/notifications/desktop_notification_service.h"
15 #include "chrome/browser/notifications/desktop_notification_service_factory.h" 21 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
22 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/extensions/api/alarms.h" 23 #include "chrome/common/extensions/api/alarms.h"
17 #include "content/public/test/browser_test.h" 24 #include "content/public/test/browser_test.h"
18 #include "content/public/test/test_utils.h" 25 #include "content/public/test/test_utils.h"
26 #include "extensions/browser/app_sorting.h"
19 #include "extensions/browser/event_router.h" 27 #include "extensions/browser/event_router.h"
20 #include "extensions/browser/extension_prefs.h" 28 #include "extensions/browser/extension_prefs.h"
29 #include "extensions/browser/extension_registry.h"
30 #include "extensions/browser/extension_registry_observer.h"
21 #include "extensions/browser/extension_system.h" 31 #include "extensions/browser/extension_system.h"
22 #include "extensions/browser/extension_util.h" 32 #include "extensions/browser/extension_util.h"
23 #include "extensions/browser/process_manager.h" 33 #include "extensions/browser/process_manager.h"
34 #include "extensions/common/extension.h"
24 #include "extensions/common/switches.h" 35 #include "extensions/common/switches.h"
36 #include "sync/api/fake_sync_change_processor.h"
37 #include "sync/api/sync_change_processor_wrapper_for_test.h"
38 #include "sync/api/sync_error_factory_mock.h"
25 #include "ui/message_center/message_center.h" 39 #include "ui/message_center/message_center.h"
26 #include "ui/message_center/notifier_settings.h" 40 #include "ui/message_center/notifier_settings.h"
27 41
42 using extensions::AppSyncData;
28 using extensions::Event; 43 using extensions::Event;
29 using extensions::EventRouter; 44 using extensions::EventRouter;
30 using extensions::Extension; 45 using extensions::Extension;
31 using extensions::ExtensionInfo; 46 using extensions::ExtensionInfo;
32 using extensions::ExtensionPrefs; 47 using extensions::ExtensionPrefs;
48 using extensions::ExtensionRegistry;
33 using extensions::ExtensionSystem; 49 using extensions::ExtensionSystem;
34 using extensions::Manifest; 50 using extensions::Manifest;
35 using extensions::PlatformAppBrowserTest;
36 51
37 namespace { 52 namespace {
38 53
39 namespace alarms = extensions::api::alarms; 54 namespace alarms = extensions::api::alarms;
40 55
41 const char kDispatchEventTestApp[] = "ephemeral_apps/dispatch_event"; 56 const char kDispatchEventTestApp[] = "ephemeral_apps/dispatch_event";
42 const char kMessagingReceiverApp[] = "ephemeral_apps/messaging_receiver";
43 const char kMessagingReceiverAppV2[] = "ephemeral_apps/messaging_receiver2";
44 const char kNotificationsTestApp[] = "ephemeral_apps/notification_settings"; 57 const char kNotificationsTestApp[] = "ephemeral_apps/notification_settings";
45 const char kFileSystemTestApp[] = "ephemeral_apps/filesystem_retain_entries"; 58 const char kFileSystemTestApp[] = "ephemeral_apps/filesystem_retain_entries";
46 const char kRetainDataApp[] = "ephemeral_apps/retain_data"; 59 const char kRetainDataApp[] = "ephemeral_apps/retain_data";
47 60
48 typedef std::vector<message_center::Notifier*> NotifierList; 61 typedef std::vector<message_center::Notifier*> NotifierList;
49 62
50 bool IsNotifierInList(const message_center::NotifierId& notifier_id, 63 bool IsNotifierInList(const message_center::NotifierId& notifier_id,
51 const NotifierList& notifiers) { 64 const NotifierList& notifiers) {
52 for (NotifierList::const_iterator it = notifiers.begin(); 65 for (NotifierList::const_iterator it = notifiers.begin();
53 it != notifiers.end(); ++it) { 66 it != notifiers.end(); ++it) {
54 const message_center::Notifier* notifier = *it; 67 const message_center::Notifier* notifier = *it;
55 if (notifier->notifier_id == notifier_id) 68 if (notifier->notifier_id == notifier_id)
56 return true; 69 return true;
57 } 70 }
58 71
59 return false; 72 return false;
60 } 73 }
61 74
62 bool IsAppInExtensionsInfo(const ExtensionPrefs::ExtensionsInfo& ext_info, 75 bool IsAppInExtensionsInfo(const ExtensionPrefs::ExtensionsInfo& ext_info,
63 const std::string& extension_id) { 76 const std::string& extension_id) {
64 for (size_t i = 0; i < ext_info.size(); ++i) { 77 for (size_t i = 0; i < ext_info.size(); ++i) {
65 ExtensionInfo* info = ext_info.at(i).get(); 78 ExtensionInfo* info = ext_info.at(i).get();
66 if (info->extension_id == extension_id) 79 if (info->extension_id == extension_id)
67 return true; 80 return true;
68 } 81 }
69 82
70 return false; 83 return false;
71 } 84 }
72 85
86 // Saves some parameters from the extension installed notification in order
87 // to verify them in tests.
88 class InstallObserver : public extensions::ExtensionRegistryObserver {
89 public:
90 struct InstallParameters {
91 std::string id;
92 bool is_update;
93 bool from_ephemeral;
94
95 InstallParameters(
96 const std::string& id,
97 bool is_update,
98 bool from_ephemeral)
99 : id(id), is_update(is_update), from_ephemeral(from_ephemeral) {}
100 };
101
102 explicit InstallObserver(Profile* profile) : profile_(profile) {
103 ExtensionRegistry::Get(profile)->AddObserver(this);
104 }
105
106 virtual ~InstallObserver() {
107 ExtensionRegistry::Get(profile_)->RemoveObserver(this);
108 }
109
110 const InstallParameters& Last() {
111 CHECK(!install_params_.empty());
112 return install_params_.back();
113 }
114
115 private:
116 virtual void OnExtensionWillBeInstalled(
117 content::BrowserContext* browser_context,
118 const Extension* extension,
119 bool is_update,
120 bool from_ephemeral,
121 const std::string& old_name) OVERRIDE {
122 install_params_.push_back(
123 InstallParameters(extension->id(), is_update, from_ephemeral));
124 }
125
126 Profile* profile_;
127 std::vector<InstallParameters> install_params_;
128 };
129
73 } // namespace 130 } // namespace
74 131
75 class EphemeralAppBrowserTest : public PlatformAppBrowserTest {
76 protected:
77 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
78 // Skip PlatformAppBrowserTest, which sets different values for the switches
79 // below.
80 ExtensionBrowserTest::SetUpCommandLine(command_line);
81 132
82 // Make event pages get suspended immediately. 133 // EphemeralAppTestBase:
83 command_line->AppendSwitchASCII( 134
84 extensions::switches::kEventPageIdleTime, "10"); 135 const char EphemeralAppTestBase::kMessagingReceiverApp[] =
85 command_line->AppendSwitchASCII( 136 "ephemeral_apps/messaging_receiver";
86 extensions::switches::kEventPageSuspendingTime, "10"); 137 const char EphemeralAppTestBase::kMessagingReceiverAppV2[] =
138 "ephemeral_apps/messaging_receiver2";
139
140 EphemeralAppTestBase::EphemeralAppTestBase() {}
141
142 EphemeralAppTestBase::~EphemeralAppTestBase() {}
143
144 void EphemeralAppTestBase::SetUpCommandLine(base::CommandLine* command_line) {
145 // Skip PlatformAppBrowserTest, which sets different values for the switches
146 // below.
147 ExtensionBrowserTest::SetUpCommandLine(command_line);
148
149 // Make event pages get suspended immediately.
150 command_line->AppendSwitchASCII(
151 extensions::switches::kEventPageIdleTime, "10");
152 command_line->AppendSwitchASCII(
153 extensions::switches::kEventPageSuspendingTime, "10");
154
155 // Enable ephemeral apps flag.
156 command_line->AppendSwitch(switches::kEnableEphemeralApps);
157 }
158
159 base::FilePath EphemeralAppTestBase::GetTestPath(const char* test_path) {
160 return test_data_dir_.AppendASCII("platform_apps").AppendASCII(test_path);
161 }
162
163 const Extension* EphemeralAppTestBase::InstallEphemeralApp(
164 const char* test_path, Manifest::Location manifest_location) {
165 const Extension* extension = InstallEphemeralAppWithSourceAndFlags(
166 GetTestPath(test_path), 1, manifest_location, Extension::NO_FLAGS);
167 return extension;
168 }
169
170 const Extension* EphemeralAppTestBase::InstallEphemeralApp(
171 const char* test_path) {
172 return InstallEphemeralApp(test_path, Manifest::INTERNAL);
173 }
174
175 const Extension* EphemeralAppTestBase::InstallAndLaunchEphemeralApp(
176 const char* test_path) {
177 ExtensionTestMessageListener launched_listener("launched", false);
178 const Extension* extension = InstallEphemeralApp(test_path);
179 EXPECT_TRUE(extension);
180 if (!extension)
181 return NULL;
182
183 LaunchPlatformApp(extension);
184 bool wait_result = launched_listener.WaitUntilSatisfied();
185 EXPECT_TRUE(wait_result);
186 if (!wait_result)
187 return NULL;
188
189 return extension;
190 }
191
192 const Extension* EphemeralAppTestBase::UpdateEphemeralApp(
193 const std::string& app_id,
194 const base::FilePath& test_dir,
195 const base::FilePath& pem_path) {
196 // Pack a new version of the app.
197 base::ScopedTempDir temp_dir;
198 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
199
200 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
201 if (!base::DeleteFile(crx_path, false)) {
202 ADD_FAILURE() << "Failed to delete existing crx: " << crx_path.value();
203 return NULL;
87 } 204 }
88 205
89 base::FilePath GetTestPath(const char* test_path) { 206 base::FilePath app_v2_path = PackExtensionWithOptions(
90 return test_data_dir_.AppendASCII("platform_apps").AppendASCII(test_path); 207 test_dir, crx_path, pem_path, base::FilePath());
91 } 208 EXPECT_FALSE(app_v2_path.empty());
92 209
93 const Extension* InstallEphemeralApp(const char* test_path, 210 // Update the ephemeral app and wait for the update to finish.
94 Manifest::Location manifest_location) { 211 extensions::CrxInstaller* crx_installer = NULL;
95 const Extension* extension = 212 content::WindowedNotificationObserver windowed_observer(
96 InstallEphemeralAppWithSourceAndFlags( 213 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
97 GetTestPath(test_path), 214 content::Source<extensions::CrxInstaller>(crx_installer));
98 1, 215 ExtensionService* service =
99 manifest_location, 216 ExtensionSystem::Get(profile())->extension_service();
100 Extension::NO_FLAGS); 217 EXPECT_TRUE(service->UpdateExtension(app_id, app_v2_path, true,
101 return extension; 218 &crx_installer));
102 } 219 windowed_observer.Wait();
103 220
104 const Extension* InstallEphemeralApp(const char* test_path) { 221 return service->GetExtensionById(app_id, false);
105 return InstallEphemeralApp(test_path, Manifest::INTERNAL); 222 }
106 }
107 223
108 const Extension* InstallAndLaunchEphemeralApp(const char* test_path) { 224 void EphemeralAppTestBase::PromoteEphemeralApp(
109 ExtensionTestMessageListener launched_listener("launched", false); 225 const extensions::Extension* app) {
110 const Extension* extension = InstallEphemeralApp(test_path); 226 ExtensionService* extension_service =
111 EXPECT_TRUE(extension); 227 ExtensionSystem::Get(profile())->extension_service();
112 if (!extension) 228 ASSERT_TRUE(extension_service);
113 return NULL; 229 extension_service->PromoteEphemeralApp(app, false);
230 }
114 231
115 LaunchPlatformApp(extension); 232 void EphemeralAppTestBase::CloseApp(const std::string& app_id) {
116 bool wait_result = launched_listener.WaitUntilSatisfied(); 233 content::WindowedNotificationObserver event_page_destroyed_signal(
117 EXPECT_TRUE(wait_result); 234 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
118 if (!wait_result) 235 content::Source<Profile>(profile()));
119 return NULL;
120 236
121 return extension; 237 EXPECT_EQ(1U, GetAppWindowCountForApp(app_id));
122 } 238 apps::AppWindow* app_window = GetFirstAppWindowForApp(app_id);
239 ASSERT_TRUE(app_window);
240 CloseAppWindow(app_window);
123 241
242 event_page_destroyed_signal.Wait();
243 }
244
245 void EphemeralAppTestBase::EvictApp(const std::string& app_id) {
246 // Uninstall the app, which is what happens when ephemeral apps get evicted
247 // from the cache.
248 content::WindowedNotificationObserver uninstalled_signal(
249 chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
250 content::Source<Profile>(profile()));
251
252 ExtensionService* service =
253 ExtensionSystem::Get(profile())->extension_service();
254 ASSERT_TRUE(service);
255 service->UninstallExtension(app_id, false, NULL);
256
257 uninstalled_signal.Wait();
258 }
259
260 // EphemeralAppBrowserTest:
261
262 class EphemeralAppBrowserTest : public EphemeralAppTestBase {
263 protected:
124 bool LaunchAppAndRunTest(const Extension* app, const char* test_name) { 264 bool LaunchAppAndRunTest(const Extension* app, const char* test_name) {
125 ExtensionTestMessageListener launched_listener("launched", true); 265 ExtensionTestMessageListener launched_listener("launched", true);
126 LaunchPlatformApp(app); 266 LaunchPlatformApp(app);
127 if (!launched_listener.WaitUntilSatisfied()) { 267 if (!launched_listener.WaitUntilSatisfied()) {
128 message_ = "Failed to receive launched message from test"; 268 message_ = "Failed to receive launched message from test";
129 return false; 269 return false;
130 } 270 }
131 271
132 ResultCatcher catcher; 272 ResultCatcher catcher;
133 launched_listener.Reply(test_name); 273 launched_listener.Reply(test_name);
134 274
135 bool result = catcher.GetNextResult(); 275 bool result = catcher.GetNextResult();
136 message_ = catcher.message(); 276 message_ = catcher.message();
137 277
138 CloseApp(app->id()); 278 CloseApp(app->id());
139 return result; 279 return result;
140 } 280 }
141 281
142 void CloseApp(const std::string& app_id) {
143 content::WindowedNotificationObserver event_page_destroyed_signal(
144 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
145 content::Source<Profile>(browser()->profile()));
146
147 EXPECT_EQ(1U, GetAppWindowCountForApp(app_id));
148 apps::AppWindow* app_window = GetFirstAppWindowForApp(app_id);
149 ASSERT_TRUE(app_window);
150 CloseAppWindow(app_window);
151
152 event_page_destroyed_signal.Wait();
153 }
154
155 void EvictApp(const std::string& app_id) {
156 // Uninstall the app, which is what happens when ephemeral apps get evicted
157 // from the cache.
158 content::WindowedNotificationObserver uninstalled_signal(
159 chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
160 content::Source<Profile>(browser()->profile()));
161
162 ExtensionService* service =
163 ExtensionSystem::Get(browser()->profile())->extension_service();
164 ASSERT_TRUE(service);
165 service->UninstallExtension(app_id, false, NULL);
166
167 uninstalled_signal.Wait();
168 }
169
170 void VerifyAppNotLoaded(const std::string& app_id) { 282 void VerifyAppNotLoaded(const std::string& app_id) {
171 EXPECT_FALSE(ExtensionSystem::Get(browser()->profile())-> 283 EXPECT_FALSE(ExtensionSystem::Get(profile())->
172 process_manager()->GetBackgroundHostForExtension(app_id)); 284 process_manager()->GetBackgroundHostForExtension(app_id));
173 } 285 }
174 286
175 void DispatchAlarmEvent(EventRouter* event_router, 287 void DispatchAlarmEvent(EventRouter* event_router,
176 const std::string& app_id) { 288 const std::string& app_id) {
177 alarms::Alarm dummy_alarm; 289 alarms::Alarm dummy_alarm;
178 dummy_alarm.name = "test_alarm"; 290 dummy_alarm.name = "test_alarm";
179 291
180 scoped_ptr<base::ListValue> args(new base::ListValue()); 292 scoped_ptr<base::ListValue> args(new base::ListValue());
181 args->Append(dummy_alarm.ToValue().release()); 293 args->Append(dummy_alarm.ToValue().release());
182 scoped_ptr<Event> event(new Event(alarms::OnAlarm::kEventName, 294 scoped_ptr<Event> event(new Event(alarms::OnAlarm::kEventName,
183 args.Pass())); 295 args.Pass()));
184 296
185 event_router->DispatchEventToExtension(app_id, event.Pass()); 297 event_router->DispatchEventToExtension(app_id, event.Pass());
186 } 298 }
187 299
188 void GarbageCollectData() { 300 void GarbageCollectData() {
189 EphemeralAppService* service = 301 EphemeralAppService* service =
190 EphemeralAppService::Get(browser()->profile()); 302 EphemeralAppService::Get(profile());
191 ASSERT_TRUE(service); 303 ASSERT_TRUE(service);
192 service->GarbageCollectData(); 304 service->GarbageCollectData();
193 } 305 }
306
307 const Extension* ReplaceEphemeralApp(const std::string& app_id,
308 const char* test_path) {
309 return UpdateExtensionWaitForIdle(app_id, GetTestPath(test_path), 0);
310 }
311
312 void VerifyInstalledApp(const std::string& app_id,
313 ExtensionRegistry::IncludeFlag expected_set) {
314 const Extension* app = ExtensionRegistry::Get(profile())->GetExtensionById(
315 app_id, expected_set);
316 ASSERT_TRUE(app);
317
318 // The app should not be ephemeral.
319 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
320 ASSERT_TRUE(prefs);
321 EXPECT_FALSE(prefs->IsEphemeralApp(app_id));
322
323 // Check sort ordinals.
324 extensions::AppSorting* app_sorting = prefs->app_sorting();
325 EXPECT_TRUE(app_sorting->GetAppLaunchOrdinal(app_id).IsValid());
326 EXPECT_TRUE(app_sorting->GetPageOrdinal(app_id).IsValid());
327 }
328
329 void InitSyncService() {
330 ExtensionSyncService* sync_service = ExtensionSyncService::Get(profile());
331 sync_service->MergeDataAndStartSyncing(
332 syncer::APPS,
333 syncer::SyncDataList(),
334 scoped_ptr<syncer::SyncChangeProcessor>(
335 new syncer::SyncChangeProcessorWrapperForTest(
336 &mock_sync_processor_)),
337 scoped_ptr<syncer::SyncErrorFactory>(
338 new syncer::SyncErrorFactoryMock()));
339 }
340
341 scoped_ptr<AppSyncData> GetFirstSyncChangeForApp(const std::string& id) {
342 scoped_ptr<AppSyncData> sync_data;
343 for (syncer::SyncChangeList::iterator it =
344 mock_sync_processor_.changes().begin();
345 it != mock_sync_processor_.changes().end(); ++it) {
346 sync_data.reset(new AppSyncData(*it));
347 if (sync_data->id() == id)
348 return sync_data.Pass();
349 }
350
351 return scoped_ptr<AppSyncData>();
352 }
353
354 void VerifySyncChange(const AppSyncData* sync_change, bool expect_enabled) {
355 ASSERT_TRUE(sync_change);
356 EXPECT_TRUE(sync_change->page_ordinal().IsValid());
357 EXPECT_TRUE(sync_change->app_launch_ordinal().IsValid());
358 EXPECT_FALSE(sync_change->uninstalled());
359 EXPECT_EQ(expect_enabled, sync_change->extension_sync_data().enabled());
360 }
361
362 syncer::FakeSyncChangeProcessor mock_sync_processor_;
194 }; 363 };
195 364
196 // Verify that ephemeral apps can be launched and receive system events when 365 // Verify that ephemeral apps can be launched and receive system events when
197 // they are running. Once they are inactive they should not receive system 366 // they are running. Once they are inactive they should not receive system
198 // events. 367 // events.
199 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, EventDispatchWhenLaunched) { 368 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, EventDispatchWhenLaunched) {
200 const Extension* extension = 369 const Extension* extension =
201 InstallAndLaunchEphemeralApp(kDispatchEventTestApp); 370 InstallAndLaunchEphemeralApp(kDispatchEventTestApp);
202 ASSERT_TRUE(extension); 371 ASSERT_TRUE(extension);
203 372
204 // Send a fake alarm event to the app and verify that a response is 373 // Send a fake alarm event to the app and verify that a response is
205 // received. 374 // received.
206 EventRouter* event_router = EventRouter::Get(browser()->profile()); 375 EventRouter* event_router = EventRouter::Get(profile());
207 ASSERT_TRUE(event_router); 376 ASSERT_TRUE(event_router);
208 377
209 ExtensionTestMessageListener alarm_received_listener("alarm_received", false); 378 ExtensionTestMessageListener alarm_received_listener("alarm_received", false);
210 DispatchAlarmEvent(event_router, extension->id()); 379 DispatchAlarmEvent(event_router, extension->id());
211 ASSERT_TRUE(alarm_received_listener.WaitUntilSatisfied()); 380 ASSERT_TRUE(alarm_received_listener.WaitUntilSatisfied());
212 381
213 CloseApp(extension->id()); 382 CloseApp(extension->id());
214 383
215 // The app needs to be launched once in order to have the onAlarm() event 384 // The app needs to be launched once in order to have the onAlarm() event
216 // registered. 385 // registered.
(...skipping 27 matching lines...) Expand all
244 // Verify that an updated ephemeral app will still have its ephemeral flag 413 // Verify that an updated ephemeral app will still have its ephemeral flag
245 // enabled. 414 // enabled.
246 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, UpdateEphemeralApp) { 415 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, UpdateEphemeralApp) {
247 const Extension* app_v1 = InstallEphemeralApp(kMessagingReceiverApp); 416 const Extension* app_v1 = InstallEphemeralApp(kMessagingReceiverApp);
248 ASSERT_TRUE(app_v1); 417 ASSERT_TRUE(app_v1);
249 ASSERT_TRUE(extensions::util::IsEphemeralApp(app_v1->id(), profile())); 418 ASSERT_TRUE(extensions::util::IsEphemeralApp(app_v1->id(), profile()));
250 std::string app_id = app_v1->id(); 419 std::string app_id = app_v1->id();
251 base::Version app_original_version = *app_v1->version(); 420 base::Version app_original_version = *app_v1->version();
252 app_v1 = NULL; // The extension object will be destroyed during update. 421 app_v1 = NULL; // The extension object will be destroyed during update.
253 422
254 // Pack version 2 of the app. 423 // Update to version 2 of the app.
255 base::ScopedTempDir temp_dir; 424 InstallObserver installed_observer(profile());
256 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 425 const Extension* app_v2 = UpdateEphemeralApp(
426 app_id, GetTestPath(kMessagingReceiverAppV2),
427 GetTestPath(kMessagingReceiverApp).ReplaceExtension(
428 FILE_PATH_LITERAL(".pem")));
257 429
258 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx"); 430 // Check the notification parameters.
259 if (!base::DeleteFile(crx_path, false)) { 431 const InstallObserver::InstallParameters& params = installed_observer.Last();
260 ADD_FAILURE() << "Failed to delete crx: " << crx_path.value(); 432 EXPECT_EQ(app_id, params.id);
261 return; 433 EXPECT_TRUE(params.is_update);
262 } 434 EXPECT_FALSE(params.from_ephemeral);
263 435
264 base::FilePath app_v2_path = PackExtensionWithOptions( 436 // The ephemeral flag should still be enabled.
265 GetTestPath(kMessagingReceiverAppV2),
266 crx_path,
267 GetTestPath(kMessagingReceiverApp).ReplaceExtension(
268 FILE_PATH_LITERAL(".pem")),
269 base::FilePath());
270 ASSERT_FALSE(app_v2_path.empty());
271
272 // Update the ephemeral app and wait for the update to finish.
273 extensions::CrxInstaller* crx_installer = NULL;
274 content::WindowedNotificationObserver windowed_observer(
275 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
276 content::Source<extensions::CrxInstaller>(crx_installer));
277 ExtensionService* service =
278 ExtensionSystem::Get(browser()->profile())->extension_service();
279 EXPECT_TRUE(service->UpdateExtension(app_id, app_v2_path, true,
280 &crx_installer));
281 windowed_observer.Wait();
282
283 const Extension* app_v2 = service->GetExtensionById(app_id, false);
284 ASSERT_TRUE(app_v2); 437 ASSERT_TRUE(app_v2);
285 EXPECT_TRUE(app_v2->version()->CompareTo(app_original_version) > 0); 438 EXPECT_TRUE(app_v2->version()->CompareTo(app_original_version) > 0);
286 EXPECT_TRUE(extensions::util::IsEphemeralApp(app_v2->id(), profile())); 439 EXPECT_TRUE(extensions::util::IsEphemeralApp(app_v2->id(), profile()));
287 } 440 }
288 441
289 // Verify that if notifications have been disabled for an ephemeral app, it will 442 // Verify that if notifications have been disabled for an ephemeral app, it will
290 // remain disabled even after being evicted from the cache. 443 // remain disabled even after being evicted from the cache.
291 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, StickyNotificationSettings) { 444 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, StickyNotificationSettings) {
292 const Extension* app = InstallEphemeralApp(kNotificationsTestApp); 445 const Extension* app = InstallEphemeralApp(kNotificationsTestApp);
293 ASSERT_TRUE(app); 446 ASSERT_TRUE(app);
294 447
295 // Disable notifications for this app. 448 // Disable notifications for this app.
296 DesktopNotificationService* notification_service = 449 DesktopNotificationService* notification_service =
297 DesktopNotificationServiceFactory::GetForProfile(browser()->profile()); 450 DesktopNotificationServiceFactory::GetForProfile(profile());
298 ASSERT_TRUE(notification_service); 451 ASSERT_TRUE(notification_service);
299 452
300 message_center::NotifierId notifier_id( 453 message_center::NotifierId notifier_id(
301 message_center::NotifierId::APPLICATION, app->id()); 454 message_center::NotifierId::APPLICATION, app->id());
302 EXPECT_TRUE(notification_service->IsNotifierEnabled(notifier_id)); 455 EXPECT_TRUE(notification_service->IsNotifierEnabled(notifier_id));
303 notification_service->SetNotifierEnabled(notifier_id, false); 456 notification_service->SetNotifierEnabled(notifier_id, false);
304 EXPECT_FALSE(notification_service->IsNotifierEnabled(notifier_id)); 457 EXPECT_FALSE(notification_service->IsNotifierEnabled(notifier_id));
305 458
306 // Remove the app. 459 // Remove the app.
307 EvictApp(app->id()); 460 EvictApp(app->id());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 "temp", temp_dir.path()); 522 "temp", temp_dir.path());
370 523
371 // The first test opens the file and writes the file handle to local storage. 524 // The first test opens the file and writes the file handle to local storage.
372 const Extension* app = InstallEphemeralApp(kFileSystemTestApp, 525 const Extension* app = InstallEphemeralApp(kFileSystemTestApp,
373 Manifest::UNPACKED); 526 Manifest::UNPACKED);
374 ASSERT_TRUE(LaunchAppAndRunTest(app, "OpenAndRetainFile")) << message_; 527 ASSERT_TRUE(LaunchAppAndRunTest(app, "OpenAndRetainFile")) << message_;
375 528
376 // Verify that after the app has been closed, all retained entries are 529 // Verify that after the app has been closed, all retained entries are
377 // flushed. 530 // flushed.
378 std::vector<apps::SavedFileEntry> file_entries = 531 std::vector<apps::SavedFileEntry> file_entries =
379 apps::SavedFilesService::Get(browser()->profile()) 532 apps::SavedFilesService::Get(profile())
380 ->GetAllFileEntries(app->id()); 533 ->GetAllFileEntries(app->id());
381 EXPECT_TRUE(file_entries.empty()); 534 EXPECT_TRUE(file_entries.empty());
382 535
383 // The second test verifies that the file cannot be reopened. 536 // The second test verifies that the file cannot be reopened.
384 ASSERT_TRUE(LaunchAppAndRunTest(app, "RestoreRetainedFile")) << message_; 537 ASSERT_TRUE(LaunchAppAndRunTest(app, "RestoreRetainedFile")) << message_;
385 } 538 }
386 539
387 // Verify that once evicted from the cache, the data of ephemeral apps will not 540 // Verify that once evicted from the cache, the data of ephemeral apps will not
388 // be deleted. 541 // be deleted.
389 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, RetainData) { 542 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, RetainData) {
390 // Phase 1 - Install the ephemeral app and write data to various storage. 543 // Phase 1 - Install the ephemeral app and write data to various storage.
391 const Extension* app = InstallEphemeralApp(kRetainDataApp); 544 const Extension* app = InstallEphemeralApp(kRetainDataApp);
392 ASSERT_TRUE(app); 545 ASSERT_TRUE(app);
393 ASSERT_TRUE(LaunchAppAndRunTest(app, "WriteData")) << message_; 546 ASSERT_TRUE(LaunchAppAndRunTest(app, "WriteData")) << message_;
394 547
395 // Sanity check to ensure that the ReadData tests should pass before the app 548 // Sanity check to ensure that the ReadData tests should pass before the app
396 // is removed. 549 // is removed.
397 ASSERT_TRUE(LaunchAppAndRunTest(app, "ReadData")) << message_; 550 ASSERT_TRUE(LaunchAppAndRunTest(app, "ReadData")) << message_;
398 551
399 // Remove the app. 552 // Remove the app.
400 const std::string app_id = app->id(); 553 const std::string app_id = app->id();
401 EvictApp(app->id()); 554 EvictApp(app->id());
402 app = NULL; 555 app = NULL;
403 556
404 // The app should be in the list of evicted apps. 557 // The app should be in the list of evicted apps.
405 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser()->profile()); 558 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
406 ASSERT_TRUE(prefs); 559 ASSERT_TRUE(prefs);
407 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( 560 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
408 prefs->GetEvictedEphemeralAppsInfo()); 561 prefs->GetEvictedEphemeralAppsInfo());
409 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, app_id)); 562 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, app_id));
410 scoped_ptr<ExtensionInfo> single_extension_info( 563 scoped_ptr<ExtensionInfo> single_extension_info(
411 prefs->GetEvictedEphemeralAppInfo(app_id)); 564 prefs->GetEvictedEphemeralAppInfo(app_id));
412 EXPECT_TRUE(single_extension_info.get()); 565 EXPECT_TRUE(single_extension_info.get());
413 566
414 // The app should not be in the list of installed extensions. 567 // The app should not be in the list of installed extensions.
415 extensions_info = prefs->GetInstalledExtensionsInfo(); 568 extensions_info = prefs->GetInstalledExtensionsInfo();
416 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id)); 569 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id));
570 EXPECT_FALSE(prefs->IsEphemeralApp(app_id));
417 571
418 // Ensure the evicted app is considered to have isolated storage. This will 572 // Ensure the evicted app is considered to have isolated storage. This will
419 // prevent its data from getting garbage collected by 573 // prevent its data from getting garbage collected by
420 // ExtensionService::GarbageCollectIsolatedStorage(). 574 // ExtensionService::GarbageCollectIsolatedStorage().
421 GURL site_url = extensions::util::GetSiteForExtensionId( 575 GURL site_url = extensions::util::GetSiteForExtensionId(
422 app_id, browser()->profile()); 576 app_id, profile());
423 EXPECT_TRUE(extensions::util::SiteHasIsolatedStorage( 577 EXPECT_TRUE(extensions::util::SiteHasIsolatedStorage(
424 site_url, browser()->profile())); 578 site_url, profile()));
425 579
426 // Phase 2 - Reinstall the ephemeral app and verify that data still exists 580 // Phase 2 - Reinstall the ephemeral app and verify that data still exists
427 // in the storage. 581 // in the storage.
428 app = InstallEphemeralApp(kRetainDataApp); 582 app = InstallEphemeralApp(kRetainDataApp);
429 ASSERT_TRUE(app); 583 ASSERT_TRUE(app);
430 EXPECT_TRUE(LaunchAppAndRunTest(app, "ReadData")) << message_; 584 EXPECT_TRUE(LaunchAppAndRunTest(app, "ReadData")) << message_;
431 585
432 // The app should now be in the list of installed extensions, but not in the 586 // The app should now be in the list of installed extensions, but not in the
433 // list of evicted apps. 587 // list of evicted apps.
434 extensions_info = prefs->GetInstalledExtensionsInfo(); 588 extensions_info = prefs->GetInstalledExtensionsInfo();
435 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, app_id)); 589 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, app_id));
436 extensions_info = prefs->GetEvictedEphemeralAppsInfo(); 590 extensions_info = prefs->GetEvictedEphemeralAppsInfo();
437 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id)); 591 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id));
438 single_extension_info = prefs->GetEvictedEphemeralAppInfo(app_id); 592 single_extension_info = prefs->GetEvictedEphemeralAppInfo(app_id);
439 EXPECT_FALSE(single_extension_info.get()); 593 EXPECT_FALSE(single_extension_info.get());
594 EXPECT_TRUE(prefs->IsEphemeralApp(app_id));
440 } 595 }
441 596
442 // Verify that preferences are updated correctly when an evicted ephemeral app 597 // Verify that preferences are updated correctly when an evicted ephemeral app
443 // is re-installed permanently. 598 // is re-installed permanently.
444 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, InstallEvictedEphemeralApp) { 599 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, InstallEvictedEphemeralApp) {
445 const Extension* app = InstallEphemeralApp(kRetainDataApp); 600 const Extension* app = InstallEphemeralApp(kRetainDataApp);
446 ASSERT_TRUE(app); 601 ASSERT_TRUE(app);
447 602
448 // Remove the app. 603 // Remove the app.
449 EvictApp(app->id()); 604 EvictApp(app->id());
450 app = NULL; 605 app = NULL;
451 606
452 // Install the app permanently. 607 // Install the app permanently.
453 app = InstallPlatformApp(kRetainDataApp); 608 app = InstallPlatformApp(kRetainDataApp);
454 ASSERT_TRUE(app); 609 ASSERT_TRUE(app);
455 610
456 // Verify that preferences are correct. 611 // Verify that preferences are correct.
457 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser()->profile()); 612 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
458 ASSERT_TRUE(prefs); 613 ASSERT_TRUE(prefs);
459 EXPECT_FALSE(prefs->IsEphemeralApp(app->id())); 614 EXPECT_FALSE(prefs->IsEphemeralApp(app->id()));
460 615
461 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( 616 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
462 prefs->GetEvictedEphemeralAppsInfo()); 617 prefs->GetEvictedEphemeralAppsInfo());
463 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app->id())); 618 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app->id()));
464 extensions_info = prefs->GetInstalledExtensionsInfo(); 619 extensions_info = prefs->GetInstalledExtensionsInfo();
465 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, app->id())); 620 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, app->id()));
466 } 621 }
467 622
468 // Verify that the data of regular installed apps are deleted on uninstall. 623 // Verify that the data of regular installed apps are deleted on uninstall.
469 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, RemoveInstalledData) { 624 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, RemoveInstalledData) {
470 // Install the ephemeral app and write data to various storage. 625 // Install the ephemeral app and write data to various storage.
471 const Extension* app = InstallPlatformApp(kRetainDataApp); 626 const Extension* app = InstallPlatformApp(kRetainDataApp);
472 ASSERT_TRUE(app); 627 ASSERT_TRUE(app);
473 ASSERT_TRUE(LaunchAppAndRunTest(app, "WriteData")) << message_; 628 ASSERT_TRUE(LaunchAppAndRunTest(app, "WriteData")) << message_;
474 629
475 // Remove the app. 630 // Remove the app.
476 const std::string app_id = app->id(); 631 const std::string app_id = app->id();
477 EvictApp(app->id()); 632 EvictApp(app->id());
478 app = NULL; 633 app = NULL;
479 634
480 // The app should not be in the preferences. 635 // The app should not be in the preferences.
481 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser()->profile()); 636 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
482 ASSERT_TRUE(prefs); 637 ASSERT_TRUE(prefs);
483 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( 638 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
484 prefs->GetEvictedEphemeralAppsInfo()); 639 prefs->GetEvictedEphemeralAppsInfo());
485 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id)); 640 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id));
486 extensions_info = prefs->GetInstalledExtensionsInfo(); 641 extensions_info = prefs->GetInstalledExtensionsInfo();
487 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id)); 642 EXPECT_FALSE(IsAppInExtensionsInfo(*extensions_info, app_id));
488 643
489 // Reinstall the app and verify that all data has been reset. 644 // Reinstall the app and verify that all data has been reset.
490 app = InstallPlatformApp(kRetainDataApp); 645 app = InstallPlatformApp(kRetainDataApp);
491 ASSERT_TRUE(LaunchAppAndRunTest(app, "DataReset")) << message_; 646 ASSERT_TRUE(LaunchAppAndRunTest(app, "DataReset")) << message_;
(...skipping 11 matching lines...) Expand all
503 std::string evict_app_id = evict_app->id(); 658 std::string evict_app_id = evict_app->id();
504 EvictApp(evict_app_id); 659 EvictApp(evict_app_id);
505 evict_app = NULL; 660 evict_app = NULL;
506 661
507 const Extension* retain_app = InstallEphemeralApp(kDispatchEventTestApp); 662 const Extension* retain_app = InstallEphemeralApp(kDispatchEventTestApp);
508 ASSERT_TRUE(retain_app); 663 ASSERT_TRUE(retain_app);
509 std::string retain_app_id = retain_app->id(); 664 std::string retain_app_id = retain_app->id();
510 EvictApp(retain_app_id); 665 EvictApp(retain_app_id);
511 retain_app = NULL; 666 retain_app = NULL;
512 667
513 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser()->profile()); 668 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
514 ASSERT_TRUE(prefs); 669 ASSERT_TRUE(prefs);
515 670
516 // Both apps should be in the list of evicted apps. 671 // Both apps should be in the list of evicted apps.
517 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( 672 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
518 prefs->GetEvictedEphemeralAppsInfo()); 673 prefs->GetEvictedEphemeralAppsInfo());
519 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, retain_app_id)); 674 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, retain_app_id));
520 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, evict_app_id)); 675 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, evict_app_id));
521 676
522 // Set a fake last launch time so that the ephemeral app's data will be 677 // Set a fake last launch time so that the ephemeral app's data will be
523 // garbage collected. 678 // garbage collected.
524 base::Time launch_time = 679 base::Time launch_time =
525 base::Time::Now() - base::TimeDelta::FromDays( 680 base::Time::Now() - base::TimeDelta::FromDays(
526 EphemeralAppService::kDataInactiveThreshold + 1); 681 EphemeralAppService::kDataInactiveThreshold + 1);
527 prefs->SetLastLaunchTime(evict_app_id, launch_time); 682 prefs->SetLastLaunchTime(evict_app_id, launch_time);
528 prefs->SetLastLaunchTime(retain_app_id, base::Time::Now()); 683 prefs->SetLastLaunchTime(retain_app_id, base::Time::Now());
529 684
530 // Garbage collect data. 685 // Garbage collect data.
531 GarbageCollectData(); 686 GarbageCollectData();
532 687
533 // The garbage collected app should no longer be in the preferences. 688 // The garbage collected app should no longer be in the preferences.
534 extensions_info = prefs->GetEvictedEphemeralAppsInfo(); 689 extensions_info = prefs->GetEvictedEphemeralAppsInfo();
535 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, retain_app_id)); 690 EXPECT_TRUE(IsAppInExtensionsInfo(*extensions_info, retain_app_id));
536 ASSERT_FALSE(IsAppInExtensionsInfo(*extensions_info, evict_app_id)); 691 ASSERT_FALSE(IsAppInExtensionsInfo(*extensions_info, evict_app_id));
537 692
538 // Reinstall the app and verify that all data has been reset. 693 // Reinstall the app and verify that all data has been reset.
539 evict_app = InstallEphemeralApp(kRetainDataApp); 694 evict_app = InstallEphemeralApp(kRetainDataApp);
540 ASSERT_TRUE(LaunchAppAndRunTest(evict_app, "DataReset")) << message_; 695 ASSERT_TRUE(LaunchAppAndRunTest(evict_app, "DataReset")) << message_;
541 } 696 }
697
698 // Checks the process of installing and then promoting an ephemeral app.
699 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteEphemeralApp) {
700 InitSyncService();
701
702 const Extension* app = InstallEphemeralApp(kRetainDataApp);
703 ASSERT_TRUE(app);
704
705 // Ephemeral apps should not be synced.
706 scoped_ptr<AppSyncData> sync_change = GetFirstSyncChangeForApp(app->id());
707 EXPECT_FALSE(sync_change.get());
708
709 // Promote the app to a regular installed app.
710 InstallObserver installed_observer(profile());
711 PromoteEphemeralApp(app);
712 VerifyInstalledApp(app->id(), ExtensionRegistry::ENABLED);
713
714 // Check the notification parameters.
715 const InstallObserver::InstallParameters& params = installed_observer.Last();
716 EXPECT_EQ(app->id(), params.id);
717 EXPECT_TRUE(params.is_update);
718 EXPECT_TRUE(params.from_ephemeral);
719
720 // The installation should now be synced.
721 sync_change = GetFirstSyncChangeForApp(app->id());
722 VerifySyncChange(sync_change.get(), true);
723 }
724
725 // Verifies that promoting an ephemeral app will enable it.
726 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteEphemeralAppAndEnable) {
727 InitSyncService();
728
729 const Extension* app = InstallEphemeralApp(kRetainDataApp);
730 ASSERT_TRUE(app);
731
732 // Disable the ephemeral app.
733 ExtensionService* service =
734 ExtensionSystem::Get(profile())->extension_service();
735 service->DisableExtension(app->id(), Extension::DISABLE_PERMISSIONS_INCREASE);
736 ASSERT_TRUE(ExtensionRegistry::Get(profile())->
737 GetExtensionById(app->id(), ExtensionRegistry::DISABLED));
738
739 // Promote to a regular installed app. It should be enabled.
740 PromoteEphemeralApp(app);
741 VerifyInstalledApp(app->id(), ExtensionRegistry::ENABLED);
742
743 scoped_ptr<AppSyncData> sync_change = GetFirstSyncChangeForApp(app->id());
744 VerifySyncChange(sync_change.get(), true);
745 }
746
747 // Verifies that promoting an ephemeral app that has unsupported requirements
748 // will not enable it.
749 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
750 PromoteUnsupportedEphemeralApp) {
751 InitSyncService();
752
753 const Extension* app = InstallEphemeralApp(kRetainDataApp);
754 ASSERT_TRUE(app);
755
756 // Disable the ephemeral app.
757 ExtensionService* service =
758 ExtensionSystem::Get(profile())->extension_service();
759 service->DisableExtension(
760 app->id(), Extension::DISABLE_UNSUPPORTED_REQUIREMENT);
761 ASSERT_TRUE(ExtensionRegistry::Get(profile())->
762 GetExtensionById(app->id(), ExtensionRegistry::DISABLED));
763
764 // Promote to a regular installed app. It should remain disabled.
765 PromoteEphemeralApp(app);
766 VerifyInstalledApp(app->id(), ExtensionRegistry::DISABLED);
767
768 scoped_ptr<AppSyncData> sync_change = GetFirstSyncChangeForApp(app->id());
769 VerifySyncChange(sync_change.get(), false);
770 }
771
772 // Checks the process of promoting an ephemeral app from sync.
773 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, PromoteEphemeralAppFromSync) {
774 InitSyncService();
775
776 const Extension* app = InstallEphemeralApp(kRetainDataApp);
777 ASSERT_TRUE(app);
778 std::string app_id = app->id();
779
780 // Simulate an install from sync.
781 const syncer::StringOrdinal kAppLaunchOrdinal("x");
782 const syncer::StringOrdinal kPageOrdinal("y");
783 AppSyncData app_sync_data(
784 *app,
785 true /* enabled */,
786 false /* incognito enabled */,
787 false /* remote install */,
788 kAppLaunchOrdinal,
789 kPageOrdinal,
790 extensions::LAUNCH_TYPE_REGULAR);
791
792 ExtensionSyncService* sync_service = ExtensionSyncService::Get(profile());
793 sync_service->ProcessAppSyncData(app_sync_data);
794
795 // Verify the installation.
796 VerifyInstalledApp(app_id, ExtensionRegistry::ENABLED);
797
798 // The sort ordinals from sync should not be overridden.
799 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
800 extensions::AppSorting* app_sorting = prefs->app_sorting();
801 EXPECT_TRUE(app_sorting->GetAppLaunchOrdinal(app_id).Equals(
802 kAppLaunchOrdinal));
803 EXPECT_TRUE(app_sorting->GetPageOrdinal(app_id).Equals(kPageOrdinal));
804 }
805
806 // In most cases, ExtensionService::PromoteEphemeralApp() will be called to
807 // permanently install an ephemeral app. However, there may be cases where an
808 // install occurs through the usual route of installing from the Web Store (due
809 // to race conditions). Ensure that the app is still installed correctly.
810 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
811 ReplaceEphemeralAppWithInstalledApp) {
812 const Extension* app = InstallEphemeralApp(kRetainDataApp);
813 ASSERT_TRUE(app);
814 std::string app_id = app->id();
815 app = NULL;
816
817 InstallObserver installed_observer(profile());
818 ReplaceEphemeralApp(app_id, kRetainDataApp);
819 VerifyInstalledApp(app_id, ExtensionRegistry::ENABLED);
820
821 // Check the notification parameters.
822 const InstallObserver::InstallParameters& params = installed_observer.Last();
823 EXPECT_EQ(app_id, params.id);
824 EXPECT_TRUE(params.is_update);
825 EXPECT_TRUE(params.from_ephemeral);
826 }
827
828 // This is similar to ReplaceEphemeralAppWithInstalledApp, but installs will
829 // be delayed until the app is idle.
830 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest,
831 ReplaceEphemeralAppWithDelayedInstalledApp) {
832 const Extension* app = InstallAndLaunchEphemeralApp(kRetainDataApp);
833 ASSERT_TRUE(app);
834 std::string app_id = app->id();
835 app = NULL;
836
837 // Initiate install.
838 ReplaceEphemeralApp(app_id, kRetainDataApp);
839
840 // The delayed installation will occur when the ephemeral app is closed.
841 content::WindowedNotificationObserver installed_signal(
842 chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED,
843 content::Source<Profile>(profile()));
844 InstallObserver installed_observer(profile());
845 CloseApp(app_id);
846 installed_signal.Wait();
847 VerifyInstalledApp(app_id, ExtensionRegistry::ENABLED);
848
849 // Check the notification parameters.
850 const InstallObserver::InstallParameters& params = installed_observer.Last();
851 EXPECT_EQ(app_id, params.id);
852 EXPECT_TRUE(params.is_update);
853 EXPECT_TRUE(params.from_ephemeral);
854 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698