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

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

Powered by Google App Engine
This is Rietveld 408576698