OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/memory/ref_counted.h" | |
6 #include "base/stl_util.h" | |
7 #include "chrome/browser/extensions/autoupdate_interceptor.h" | |
8 #include "chrome/browser/extensions/extension_browsertest.h" | |
9 #include "chrome/browser/extensions/extension_host.h" | |
10 #include "chrome/browser/extensions/extension_service.h" | |
11 #include "chrome/browser/extensions/extension_test_message_listener.h" | |
12 #include "chrome/browser/extensions/updater/extension_updater.h" | |
13 #include "chrome/browser/infobars/infobar_tab_helper.h" | |
14 #include "chrome/browser/prefs/pref_service.h" | |
15 #include "chrome/browser/prefs/scoped_user_pref_update.h" | |
16 #include "chrome/browser/profiles/profile.h" | |
17 #include "chrome/browser/ui/browser.h" | |
18 #include "chrome/browser/ui/tab_contents/tab_contents.h" | |
19 #include "chrome/common/chrome_notification_types.h" | |
20 #include "chrome/common/pref_names.h" | |
21 #include "chrome/common/url_constants.h" | |
22 #include "chrome/test/base/ui_test_utils.h" | |
23 #include "content/public/browser/notification_service.h" | |
24 #include "content/public/browser/render_view_host.h" | |
25 #include "content/public/test/browser_test_utils.h" | |
26 #include "net/url_request/url_fetcher.h" | |
27 | |
28 using extensions::Extension; | |
29 | |
30 class ExtensionManagementTest : public ExtensionBrowserTest { | |
31 protected: | |
32 // Helper method that returns whether the extension is at the given version. | |
33 // This calls version(), which must be defined in the extension's bg page, | |
34 // as well as asking the extension itself. | |
35 // | |
36 // Note that 'version' here means something different than the version field | |
37 // in the extension's manifest. We use the version as reported by the | |
38 // background page to test how overinstalling crx files with the same | |
39 // manifest version works. | |
40 bool IsExtensionAtVersion(const Extension* extension, | |
41 const std::string& expected_version) { | |
42 // Test that the extension's version from the manifest and reported by the | |
43 // background page is correct. This is to ensure that the processes are in | |
44 // sync with the Extension. | |
45 ExtensionProcessManager* manager = browser()->profile()-> | |
46 GetExtensionProcessManager(); | |
47 extensions::ExtensionHost* ext_host = | |
48 manager->GetBackgroundHostForExtension(extension->id()); | |
49 EXPECT_TRUE(ext_host); | |
50 if (!ext_host) | |
51 return false; | |
52 | |
53 std::string version_from_bg; | |
54 bool exec = content::ExecuteJavaScriptAndExtractString( | |
55 ext_host->render_view_host(), L"", L"version()", &version_from_bg); | |
56 EXPECT_TRUE(exec); | |
57 if (!exec) | |
58 return false; | |
59 | |
60 if (version_from_bg != expected_version || | |
61 extension->VersionString() != expected_version) | |
62 return false; | |
63 return true; | |
64 } | |
65 }; | |
66 | |
67 #if defined(OS_LINUX) | |
68 // Times out sometimes on Linux. http://crbug.com/89727 | |
69 #define MAYBE_InstallSameVersion DISABLED_InstallSameVersion | |
70 #else | |
71 #define MAYBE_InstallSameVersion InstallSameVersion | |
72 #endif | |
73 | |
74 // Tests that installing the same version overwrites. | |
75 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_InstallSameVersion) { | |
76 const Extension* extension = InstallExtension( | |
77 test_data_dir_.AppendASCII("install/install.crx"), 1); | |
78 ASSERT_TRUE(extension); | |
79 FilePath old_path = extension->path(); | |
80 | |
81 // Install an extension with the same version. The previous install should be | |
82 // overwritten. | |
83 extension = InstallExtension( | |
84 test_data_dir_.AppendASCII("install/install_same_version.crx"), 0); | |
85 ASSERT_TRUE(extension); | |
86 FilePath new_path = extension->path(); | |
87 | |
88 EXPECT_FALSE(IsExtensionAtVersion(extension, "1.0")); | |
89 EXPECT_NE(old_path.value(), new_path.value()); | |
90 } | |
91 | |
92 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallOlderVersion) { | |
93 const Extension* extension = InstallExtension( | |
94 test_data_dir_.AppendASCII("install/install.crx"), 1); | |
95 ASSERT_TRUE(extension); | |
96 ASSERT_FALSE(InstallExtension( | |
97 test_data_dir_.AppendASCII("install/install_older_version.crx"), 0)); | |
98 EXPECT_TRUE(IsExtensionAtVersion(extension, "1.0")); | |
99 } | |
100 | |
101 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallThenCancel) { | |
102 const Extension* extension = InstallExtension( | |
103 test_data_dir_.AppendASCII("install/install.crx"), 1); | |
104 ASSERT_TRUE(extension); | |
105 | |
106 // Cancel this install. | |
107 ASSERT_FALSE(StartInstallButCancel( | |
108 test_data_dir_.AppendASCII("install/install_v2.crx"))); | |
109 EXPECT_TRUE(IsExtensionAtVersion(extension, "1.0")); | |
110 } | |
111 | |
112 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallRequiresConfirm) { | |
113 // Installing the extension without an auto confirming UI should result in | |
114 // it being disabled, since good.crx has permissions that require approval. | |
115 ExtensionService* service = browser()->profile()->GetExtensionService(); | |
116 std::string id = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; | |
117 ASSERT_FALSE(InstallExtension(test_data_dir_.AppendASCII("good.crx"), 0)); | |
118 ASSERT_TRUE(service->GetExtensionById(id, true)); | |
119 UninstallExtension(id); | |
120 | |
121 // And the install should succeed when the permissions are accepted. | |
122 ASSERT_TRUE(InstallExtensionWithUIAutoConfirm( | |
123 test_data_dir_.AppendASCII("good.crx"), 1, browser())); | |
124 UninstallExtension(id); | |
125 } | |
126 | |
127 // Tests that disabling and re-enabling an extension works. | |
128 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableEnable) { | |
129 ExtensionProcessManager* manager = browser()->profile()-> | |
130 GetExtensionProcessManager(); | |
131 ExtensionService* service = browser()->profile()->GetExtensionService(); | |
132 const size_t size_before = service->extensions()->size(); | |
133 | |
134 // Load an extension, expect the background page to be available. | |
135 std::string extension_id = "bjafgdebaacbbbecmhlhpofkepfkgcpa"; | |
136 ASSERT_TRUE(LoadExtension( | |
137 test_data_dir_.AppendASCII("good").AppendASCII("Extensions") | |
138 .AppendASCII(extension_id) | |
139 .AppendASCII("1.0"))); | |
140 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
141 EXPECT_EQ(0u, service->disabled_extensions()->size()); | |
142 EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id)); | |
143 | |
144 // After disabling, the background page should go away. | |
145 DisableExtension(extension_id); | |
146 EXPECT_EQ(size_before, service->extensions()->size()); | |
147 EXPECT_EQ(1u, service->disabled_extensions()->size()); | |
148 EXPECT_FALSE(manager->GetBackgroundHostForExtension(extension_id)); | |
149 | |
150 // And bring it back. | |
151 EnableExtension(extension_id); | |
152 EXPECT_EQ(size_before + 1, service->extensions()->size()); | |
153 EXPECT_EQ(0u, service->disabled_extensions()->size()); | |
154 EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id)); | |
155 } | |
156 | |
157 // Used for testing notifications sent during extension updates. | |
158 class NotificationListener : public content::NotificationObserver { | |
159 public: | |
160 NotificationListener() : started_(false), finished_(false) { | |
161 int types[] = { | |
162 chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED, | |
163 chrome::NOTIFICATION_EXTENSION_UPDATING_FINISHED, | |
164 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND | |
165 }; | |
166 for (size_t i = 0; i < arraysize(types); i++) { | |
167 registrar_.Add( | |
168 this, types[i], content::NotificationService::AllSources()); | |
169 } | |
170 } | |
171 ~NotificationListener() {} | |
172 | |
173 bool started() { return started_; } | |
174 | |
175 bool finished() { return finished_; } | |
176 | |
177 const std::set<std::string>& updates() { return updates_; } | |
178 | |
179 void Reset() { | |
180 started_ = false; | |
181 finished_ = false; | |
182 updates_.clear(); | |
183 } | |
184 | |
185 // Implements content::NotificationObserver interface. | |
186 virtual void Observe(int type, | |
187 const content::NotificationSource& source, | |
188 const content::NotificationDetails& details) { | |
189 switch (type) { | |
190 case chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED: { | |
191 EXPECT_FALSE(started_); | |
192 started_ = true; | |
193 break; | |
194 } | |
195 case chrome::NOTIFICATION_EXTENSION_UPDATING_FINISHED: { | |
196 EXPECT_FALSE(finished_); | |
197 finished_ = true; | |
198 break; | |
199 } | |
200 case chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND: { | |
201 const std::string* id = | |
202 content::Details<const std::string>(details).ptr(); | |
203 updates_.insert(*id); | |
204 break; | |
205 } | |
206 default: | |
207 NOTREACHED(); | |
208 } | |
209 } | |
210 | |
211 private: | |
212 content::NotificationRegistrar registrar_; | |
213 | |
214 // Did we see EXTENSION_UPDATING_STARTED? | |
215 bool started_; | |
216 | |
217 // Did we see EXTENSION_UPDATING_FINISHED? | |
218 bool finished_; | |
219 | |
220 // The set of extension id's we've seen via EXTENSION_UPDATE_FOUND. | |
221 std::set<std::string> updates_; | |
222 }; | |
223 | |
224 #if defined(OS_WIN) | |
225 // Fails consistently on Windows XP, see: http://crbug.com/120640. | |
226 #define MAYBE_AutoUpdate DISABLED_AutoUpdate | |
227 #else | |
228 // See http://crbug.com/103371 and http://crbug.com/120640. | |
229 #if defined(ADDRESS_SANITIZER) | |
230 #define MAYBE_AutoUpdate DISABLED_AutoUpdate | |
231 #else | |
232 #define MAYBE_AutoUpdate AutoUpdate | |
233 #endif | |
234 #endif | |
235 | |
236 // Tests extension autoupdate. | |
237 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_AutoUpdate) { | |
238 NotificationListener notification_listener; | |
239 FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); | |
240 // Note: This interceptor gets requests on the IO thread. | |
241 scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor()); | |
242 net::URLFetcher::SetEnableInterceptionForTests(true); | |
243 | |
244 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest", | |
245 basedir.AppendASCII("manifest_v2.xml")); | |
246 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx", | |
247 basedir.AppendASCII("v2.crx")); | |
248 | |
249 // Install version 1 of the extension. | |
250 ExtensionTestMessageListener listener1("v1 installed", false); | |
251 ExtensionService* service = browser()->profile()->GetExtensionService(); | |
252 const size_t size_before = service->extensions()->size(); | |
253 ASSERT_TRUE(service->disabled_extensions()->is_empty()); | |
254 const Extension* extension = | |
255 InstallExtension(basedir.AppendASCII("v1.crx"), 1); | |
256 ASSERT_TRUE(extension); | |
257 listener1.WaitUntilSatisfied(); | |
258 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
259 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id()); | |
260 ASSERT_EQ("1.0", extension->VersionString()); | |
261 | |
262 // We don't want autoupdate blacklist checks. | |
263 service->updater()->set_blacklist_checks_enabled(false); | |
264 | |
265 // Run autoupdate and make sure version 2 of the extension was installed. | |
266 ExtensionTestMessageListener listener2("v2 installed", false); | |
267 service->updater()->CheckNow(); | |
268 ASSERT_TRUE(WaitForExtensionInstall()); | |
269 listener2.WaitUntilSatisfied(); | |
270 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
271 extension = service->GetExtensionById( | |
272 "ogjcoiohnmldgjemafoockdghcjciccf", false); | |
273 ASSERT_TRUE(extension); | |
274 ASSERT_EQ("2.0", extension->VersionString()); | |
275 ASSERT_TRUE(notification_listener.started()); | |
276 ASSERT_TRUE(notification_listener.finished()); | |
277 ASSERT_TRUE(ContainsKey(notification_listener.updates(), | |
278 "ogjcoiohnmldgjemafoockdghcjciccf")); | |
279 notification_listener.Reset(); | |
280 | |
281 // Now try doing an update to version 3, which has been incorrectly | |
282 // signed. This should fail. | |
283 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest", | |
284 basedir.AppendASCII("manifest_v3.xml")); | |
285 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v3.crx", | |
286 basedir.AppendASCII("v3.crx")); | |
287 | |
288 service->updater()->CheckNow(); | |
289 ASSERT_TRUE(WaitForExtensionInstallError()); | |
290 ASSERT_TRUE(notification_listener.started()); | |
291 ASSERT_TRUE(notification_listener.finished()); | |
292 ASSERT_TRUE(ContainsKey(notification_listener.updates(), | |
293 "ogjcoiohnmldgjemafoockdghcjciccf")); | |
294 | |
295 // Make sure the extension state is the same as before. | |
296 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
297 extension = service->GetExtensionById( | |
298 "ogjcoiohnmldgjemafoockdghcjciccf", false); | |
299 ASSERT_TRUE(extension); | |
300 ASSERT_EQ("2.0", extension->VersionString()); | |
301 } | |
302 | |
303 #if defined(OS_WIN) | |
304 // Fails consistently on Windows XP, see: http://crbug.com/120640. | |
305 #define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions | |
306 #else | |
307 #if defined(ADDRESS_SANITIZER) | |
308 #define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions | |
309 #else | |
310 #define MAYBE_AutoUpdateDisabledExtensions AutoUpdateDisabledExtensions | |
311 #endif | |
312 #endif | |
313 | |
314 // Tests extension autoupdate. | |
315 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, | |
316 MAYBE_AutoUpdateDisabledExtensions) { | |
317 NotificationListener notification_listener; | |
318 FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); | |
319 // Note: This interceptor gets requests on the IO thread. | |
320 scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor()); | |
321 net::URLFetcher::SetEnableInterceptionForTests(true); | |
322 | |
323 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest", | |
324 basedir.AppendASCII("manifest_v2.xml")); | |
325 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx", | |
326 basedir.AppendASCII("v2.crx")); | |
327 | |
328 // Install version 1 of the extension. | |
329 ExtensionTestMessageListener listener1("v1 installed", false); | |
330 ExtensionService* service = browser()->profile()->GetExtensionService(); | |
331 const size_t enabled_size_before = service->extensions()->size(); | |
332 const size_t disabled_size_before = service->disabled_extensions()->size(); | |
333 const Extension* extension = | |
334 InstallExtension(basedir.AppendASCII("v1.crx"), 1); | |
335 ASSERT_TRUE(extension); | |
336 listener1.WaitUntilSatisfied(); | |
337 DisableExtension(extension->id()); | |
338 ASSERT_EQ(disabled_size_before + 1, service->disabled_extensions()->size()); | |
339 ASSERT_EQ(enabled_size_before, service->extensions()->size()); | |
340 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id()); | |
341 ASSERT_EQ("1.0", extension->VersionString()); | |
342 | |
343 // We don't want autoupdate blacklist checks. | |
344 service->updater()->set_blacklist_checks_enabled(false); | |
345 | |
346 ExtensionTestMessageListener listener2("v2 installed", false); | |
347 // Run autoupdate and make sure version 2 of the extension was installed but | |
348 // is still disabled. | |
349 service->updater()->CheckNow(); | |
350 ASSERT_TRUE(WaitForExtensionInstall()); | |
351 ASSERT_EQ(disabled_size_before + 1, service->disabled_extensions()->size()); | |
352 ASSERT_EQ(enabled_size_before, service->extensions()->size()); | |
353 extension = service->GetExtensionById( | |
354 "ogjcoiohnmldgjemafoockdghcjciccf", true); | |
355 ASSERT_TRUE(extension); | |
356 ASSERT_FALSE(service->GetExtensionById( | |
357 "ogjcoiohnmldgjemafoockdghcjciccf", false)); | |
358 ASSERT_EQ("2.0", extension->VersionString()); | |
359 | |
360 // The extension should have not made the callback because it is disabled. | |
361 // When we enabled it, it should then make the callback. | |
362 ASSERT_FALSE(listener2.was_satisfied()); | |
363 EnableExtension(extension->id()); | |
364 listener2.WaitUntilSatisfied(); | |
365 ASSERT_TRUE(notification_listener.started()); | |
366 ASSERT_TRUE(notification_listener.finished()); | |
367 ASSERT_TRUE(ContainsKey(notification_listener.updates(), | |
368 "ogjcoiohnmldgjemafoockdghcjciccf")); | |
369 notification_listener.Reset(); | |
370 } | |
371 | |
372 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) { | |
373 ExtensionService* service = browser()->profile()->GetExtensionService(); | |
374 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; | |
375 // We don't want autoupdate blacklist checks. | |
376 service->updater()->set_blacklist_checks_enabled(false); | |
377 | |
378 FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); | |
379 | |
380 // Note: This interceptor gets requests on the IO thread. | |
381 scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor()); | |
382 net::URLFetcher::SetEnableInterceptionForTests(true); | |
383 | |
384 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest", | |
385 basedir.AppendASCII("manifest_v2.xml")); | |
386 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx", | |
387 basedir.AppendASCII("v2.crx")); | |
388 | |
389 const size_t size_before = service->extensions()->size(); | |
390 ASSERT_TRUE(service->disabled_extensions()->is_empty()); | |
391 | |
392 extensions::PendingExtensionManager* pending_extension_manager = | |
393 service->pending_extension_manager(); | |
394 | |
395 // The code that reads external_extensions.json uses this method to inform | |
396 // the ExtensionService of an extension to download. Using the real code | |
397 // is race-prone, because instantating the ExtensionService starts a read | |
398 // of external_extensions.json before this test function starts. | |
399 | |
400 EXPECT_TRUE(pending_extension_manager->AddFromExternalUpdateUrl( | |
401 kExtensionId, GURL("http://localhost/autoupdate/manifest"), | |
402 Extension::EXTERNAL_PREF_DOWNLOAD)); | |
403 | |
404 // Run autoupdate and make sure version 2 of the extension was installed. | |
405 service->updater()->CheckNow(); | |
406 ASSERT_TRUE(WaitForExtensionInstall()); | |
407 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
408 const Extension* extension = service->GetExtensionById(kExtensionId, false); | |
409 ASSERT_TRUE(extension); | |
410 ASSERT_EQ("2.0", extension->VersionString()); | |
411 | |
412 // Uninstalling the extension should set a pref that keeps the extension from | |
413 // being installed again the next time external_extensions.json is read. | |
414 | |
415 UninstallExtension(kExtensionId); | |
416 | |
417 extensions::ExtensionPrefs* extension_prefs = service->extension_prefs(); | |
418 EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) | |
419 << "Uninstalling should set kill bit on externaly installed extension."; | |
420 | |
421 // Try to install the extension again from an external source. It should fail | |
422 // because of the killbit. | |
423 EXPECT_FALSE(pending_extension_manager->AddFromExternalUpdateUrl( | |
424 kExtensionId, GURL("http://localhost/autoupdate/manifest"), | |
425 Extension::EXTERNAL_PREF_DOWNLOAD)); | |
426 EXPECT_FALSE(pending_extension_manager->IsIdPending(kExtensionId)) | |
427 << "External reinstall of a killed extension shouldn't work."; | |
428 EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) | |
429 << "External reinstall of a killed extension should leave it killed."; | |
430 | |
431 // Installing from non-external source. | |
432 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1)); | |
433 | |
434 EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) | |
435 << "Reinstalling should clear the kill bit."; | |
436 | |
437 // Uninstalling from a non-external source should not set the kill bit. | |
438 UninstallExtension(kExtensionId); | |
439 | |
440 EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) | |
441 << "Uninstalling non-external extension should not set kill bit."; | |
442 } | |
443 | |
444 namespace { | |
445 | |
446 const char* kForceInstallNotEmptyHelp = | |
447 "A policy may already be controlling the list of force-installed " | |
448 "extensions. Please remove all policy settings from your computer " | |
449 "before running tests. E.g. from /etc/chromium/policies Linux or " | |
450 "from the registry on Windows, etc."; | |
451 | |
452 } | |
453 | |
454 // See http://crbug.com/57378 for flakiness details. | |
455 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) { | |
456 ExtensionService* service = browser()->profile()->GetExtensionService(); | |
457 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; | |
458 // We don't want autoupdate blacklist checks. | |
459 service->updater()->set_blacklist_checks_enabled(false); | |
460 | |
461 FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); | |
462 | |
463 // Note: This interceptor gets requests on the IO thread. | |
464 scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor()); | |
465 net::URLFetcher::SetEnableInterceptionForTests(true); | |
466 | |
467 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest", | |
468 basedir.AppendASCII("manifest_v2.xml")); | |
469 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx", | |
470 basedir.AppendASCII("v2.crx")); | |
471 | |
472 const size_t size_before = service->extensions()->size(); | |
473 ASSERT_TRUE(service->disabled_extensions()->is_empty()); | |
474 | |
475 PrefService* prefs = browser()->profile()->GetPrefs(); | |
476 const ListValue* forcelist = | |
477 prefs->GetList(prefs::kExtensionInstallForceList); | |
478 ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp; | |
479 | |
480 { | |
481 // Set the policy as a user preference and fire notification observers. | |
482 ListPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList); | |
483 ListValue* forcelist = pref_update.Get(); | |
484 ASSERT_TRUE(forcelist->empty()); | |
485 forcelist->Append(Value::CreateStringValue( | |
486 std::string(kExtensionId) + | |
487 ";http://localhost/autoupdate/manifest")); | |
488 } | |
489 | |
490 // Check if the extension got installed. | |
491 ASSERT_TRUE(WaitForExtensionInstall()); | |
492 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
493 const Extension* extension = service->GetExtensionById(kExtensionId, false); | |
494 ASSERT_TRUE(extension); | |
495 ASSERT_EQ("2.0", extension->VersionString()); | |
496 EXPECT_EQ(Extension::EXTERNAL_POLICY_DOWNLOAD, extension->location()); | |
497 | |
498 // Try to disable and uninstall the extension which should fail. | |
499 DisableExtension(kExtensionId); | |
500 EXPECT_EQ(size_before + 1, service->extensions()->size()); | |
501 EXPECT_EQ(0u, service->disabled_extensions()->size()); | |
502 UninstallExtension(kExtensionId); | |
503 EXPECT_EQ(size_before + 1, service->extensions()->size()); | |
504 EXPECT_EQ(0u, service->disabled_extensions()->size()); | |
505 | |
506 // Now try to disable it through the management api, again failing. | |
507 ExtensionTestMessageListener listener1("ready", false); | |
508 ASSERT_TRUE(LoadExtension( | |
509 test_data_dir_.AppendASCII("management/uninstall_extension"))); | |
510 ASSERT_TRUE(listener1.WaitUntilSatisfied()); | |
511 EXPECT_EQ(size_before + 2, service->extensions()->size()); | |
512 EXPECT_EQ(0u, service->disabled_extensions()->size()); | |
513 | |
514 // Check that emptying the list triggers uninstall. | |
515 { | |
516 prefs->ClearPref(prefs::kExtensionInstallForceList); | |
517 } | |
518 EXPECT_EQ(size_before + 1, service->extensions()->size()); | |
519 EXPECT_FALSE(service->GetExtensionById(kExtensionId, true)); | |
520 } | |
521 | |
522 // See http://crbug.com/103371 and http://crbug.com/120640. | |
523 #if defined(ADDRESS_SANITIZER) | |
524 #define MAYBE_PolicyOverridesUserInstall DISABLED_PolicyOverridesUserInstall | |
525 #else | |
526 #define MAYBE_PolicyOverridesUserInstall PolicyOverridesUserInstall | |
527 #endif | |
528 | |
529 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, | |
530 MAYBE_PolicyOverridesUserInstall) { | |
531 ExtensionService* service = browser()->profile()->GetExtensionService(); | |
532 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; | |
533 service->updater()->set_blacklist_checks_enabled(false); | |
534 const size_t size_before = service->extensions()->size(); | |
535 FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); | |
536 ASSERT_TRUE(service->disabled_extensions()->is_empty()); | |
537 | |
538 // Note: This interceptor gets requests on the IO thread. | |
539 scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor()); | |
540 net::URLFetcher::SetEnableInterceptionForTests(true); | |
541 | |
542 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest", | |
543 basedir.AppendASCII("manifest_v2.xml")); | |
544 interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx", | |
545 basedir.AppendASCII("v2.crx")); | |
546 | |
547 // Check that the policy is initially empty. | |
548 PrefService* prefs = browser()->profile()->GetPrefs(); | |
549 const ListValue* forcelist = | |
550 prefs->GetList(prefs::kExtensionInstallForceList); | |
551 ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp; | |
552 | |
553 // User install of the extension. | |
554 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1)); | |
555 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
556 const Extension* extension = service->GetExtensionById(kExtensionId, false); | |
557 ASSERT_TRUE(extension); | |
558 EXPECT_EQ(Extension::INTERNAL, extension->location()); | |
559 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); | |
560 | |
561 // Setup the force install policy. It should override the location. | |
562 { | |
563 ListPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList); | |
564 ListValue* forcelist = pref_update.Get(); | |
565 ASSERT_TRUE(forcelist->empty()); | |
566 forcelist->Append(Value::CreateStringValue( | |
567 std::string(kExtensionId) + ";http://localhost/autoupdate/manifest")); | |
568 } | |
569 ASSERT_TRUE(WaitForExtensionInstall()); | |
570 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
571 extension = service->GetExtensionById(kExtensionId, false); | |
572 ASSERT_TRUE(extension); | |
573 EXPECT_EQ(Extension::EXTERNAL_POLICY_DOWNLOAD, extension->location()); | |
574 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); | |
575 | |
576 // Remove the policy, and verify that the extension was uninstalled. | |
577 // TODO(joaodasilva): it would be nicer if the extension was kept instead, | |
578 // and reverted location to INTERNAL or whatever it was before the policy | |
579 // was applied. | |
580 { | |
581 ListPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList); | |
582 ListValue* forcelist = pref_update.Get(); | |
583 ASSERT_TRUE(!forcelist->empty()); | |
584 forcelist->Clear(); | |
585 } | |
586 ASSERT_EQ(size_before, service->extensions()->size()); | |
587 extension = service->GetExtensionById(kExtensionId, true); | |
588 EXPECT_FALSE(extension); | |
589 | |
590 // User install again, but have it disabled too before setting the policy. | |
591 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1)); | |
592 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
593 extension = service->GetExtensionById(kExtensionId, false); | |
594 ASSERT_TRUE(extension); | |
595 EXPECT_EQ(Extension::INTERNAL, extension->location()); | |
596 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); | |
597 EXPECT_TRUE(service->disabled_extensions()->is_empty()); | |
598 | |
599 DisableExtension(kExtensionId); | |
600 EXPECT_EQ(1u, service->disabled_extensions()->size()); | |
601 extension = service->GetExtensionById(kExtensionId, true); | |
602 EXPECT_TRUE(extension); | |
603 EXPECT_FALSE(service->IsExtensionEnabled(kExtensionId)); | |
604 | |
605 // Install the policy again. It should overwrite the extension's location, | |
606 // and force enable it too. | |
607 { | |
608 ListPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList); | |
609 ListValue* forcelist = pref_update.Get(); | |
610 ASSERT_TRUE(forcelist->empty()); | |
611 forcelist->Append(Value::CreateStringValue( | |
612 std::string(kExtensionId) + ";http://localhost/autoupdate/manifest")); | |
613 } | |
614 ASSERT_TRUE(WaitForExtensionInstall()); | |
615 ASSERT_EQ(size_before + 1, service->extensions()->size()); | |
616 extension = service->GetExtensionById(kExtensionId, false); | |
617 ASSERT_TRUE(extension); | |
618 EXPECT_EQ(Extension::EXTERNAL_POLICY_DOWNLOAD, extension->location()); | |
619 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); | |
620 EXPECT_TRUE(service->disabled_extensions()->is_empty()); | |
621 } | |
OLD | NEW |