blob: 80261046aa50700ff353f7d9acaf7f90dc54d5c4 [file] [log] [blame]
[email protected]098fa7a2013-03-08 22:11:171// Copyright (c) 2013 The Chromium Authors. All rights reserved.
[email protected]6014d672008-12-05 00:38:252// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
dcheng1fc00f12015-12-26 22:18:035#include "chrome/browser/extensions/extension_service.h"
6
avia2f4804a2015-12-24 23:11:137#include <stddef.h>
8#include <stdint.h>
dchengc963c7142016-04-08 03:55:229
[email protected]f0397fa2008-12-11 17:59:5810#include <algorithm>
treib9afc6212015-10-30 18:49:5811#include <map>
dchengc963c7142016-04-08 03:55:2212#include <memory>
[email protected]7fa19f82010-12-21 19:40:0813#include <set>
treib9afc6212015-10-30 18:49:5814#include <string>
dcheng1fc00f12015-12-26 22:18:0315#include <utility>
[email protected]6014d672008-12-05 00:38:2516#include <vector>
17
[email protected]be5a6db2012-11-13 14:39:1118#include "base/at_exit.h"
[email protected]c4148a72011-08-09 23:04:2019#include "base/bind.h"
[email protected]36a784c2009-06-23 06:21:0820#include "base/command_line.h"
thestig18dfb7a52014-08-26 10:44:0421#include "base/files/file_util.h"
[email protected]ea1a3f62012-11-16 20:34:2322#include "base/files/scoped_temp_dir.h"
[email protected]ffbec692012-02-26 20:26:4223#include "base/json/json_file_value_serializer.h"
[email protected]93d49d72009-10-23 20:00:2024#include "base/json/json_reader.h"
[email protected]ffbec692012-02-26 20:26:4225#include "base/json/json_string_value_serializer.h"
skyostilf221b7de2015-06-11 20:36:3226#include "base/location.h"
dchengc963c7142016-04-08 03:55:2227#include "base/memory/ptr_util.h"
fdoraycb32419d2016-06-23 15:52:5528#include "base/run_loop.h"
skyostilf221b7de2015-06-11 20:36:3229#include "base/single_thread_task_runner.h"
[email protected]7286e3fc2011-07-19 22:13:2430#include "base/stl_util.h"
brettwd97eede2015-07-06 22:09:0031#include "base/strings/pattern.h"
[email protected]00e7bef2013-06-10 20:35:1732#include "base/strings/string16.h"
[email protected]3ea1b182013-02-08 22:38:4133#include "base/strings/string_number_conversions.h"
[email protected]00e7bef2013-06-10 20:35:1734#include "base/strings/string_util.h"
Lei Zhangfe5b86932019-02-01 17:26:5935#include "base/strings/stringprintf.h"
[email protected]112158af2013-06-07 23:46:1836#include "base/strings/utf_string_conversions.h"
Randy Smithe93faff2017-12-22 14:28:5237#include "base/time/time.h"
vabr9984ea62017-04-10 11:33:4938#include "base/values.h"
[email protected]aa142702010-03-26 01:26:3339#include "base/version.h"
avia2f4804a2015-12-24 23:11:1340#include "build/build_config.h"
[email protected]9d32ded072011-10-11 16:31:0541#include "chrome/browser/browser_process.h"
[email protected]9ea0cd32013-07-12 01:50:3642#include "chrome/browser/chrome_notification_types.h"
[email protected]3f2a2fa2013-09-24 02:55:2543#include "chrome/browser/extensions/blacklist.h"
[email protected]74474042013-11-21 12:03:5444#include "chrome/browser/extensions/chrome_app_sorting.h"
Maks Orlovich710d5e32019-07-09 20:16:4545#include "chrome/browser/extensions/chrome_extension_cookies.h"
rdevlin.croninf87d15f2017-01-26 22:57:1946#include "chrome/browser/extensions/chrome_test_extension_loader.h"
[email protected]d8c8f25f2011-11-02 18:18:0147#include "chrome/browser/extensions/component_loader.h"
[email protected]eb6c7ef2011-12-12 23:12:2048#include "chrome/browser/extensions/crx_installer.h"
[email protected]a7cd28e2012-10-05 21:03:3649#include "chrome/browser/extensions/default_apps.h"
[email protected]89226982012-07-16 20:09:1850#include "chrome/browser/extensions/extension_error_ui.h"
binjinb2454382014-09-22 15:17:4351#include "chrome/browser/extensions/extension_management_test_util.h"
[email protected]f484f8d52014-06-12 08:38:1852#include "chrome/browser/extensions/extension_service_test_base.h"
treib9afc6212015-10-30 18:49:5853#include "chrome/browser/extensions/extension_service_test_with_install.h"
[email protected]19eb80152011-02-26 00:28:4354#include "chrome/browser/extensions/extension_special_storage_policy.h"
[email protected]a7ff4b72013-10-17 20:56:0255#include "chrome/browser/extensions/extension_util.h"
[email protected]2894a512014-06-26 19:03:5656#include "chrome/browser/extensions/external_install_error.h"
57#include "chrome/browser/extensions/external_install_manager.h"
[email protected]e410b5f2012-12-14 14:02:2458#include "chrome/browser/extensions/external_policy_loader.h"
[email protected]5df038b2012-07-16 19:03:2759#include "chrome/browser/extensions/external_pref_loader.h"
60#include "chrome/browser/extensions/external_provider_impl.h"
[email protected]3f2a2fa2013-09-24 02:55:2561#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
[email protected]d8c8f25f2011-11-02 18:18:0162#include "chrome/browser/extensions/installed_loader.h"
Devlin Cronin9722a722017-12-16 03:35:1063#include "chrome/browser/extensions/load_error_reporter.h"
[email protected]f0bfe622012-06-22 01:01:4464#include "chrome/browser/extensions/pack_extension_job.h"
[email protected]f3d3b382014-03-14 21:19:2865#include "chrome/browser/extensions/pending_extension_info.h"
66#include "chrome/browser/extensions/pending_extension_manager.h"
Takashi Toyoshima69579072018-11-19 07:10:5067#include "chrome/browser/extensions/permissions_test_util.h"
binjine6b58b52014-10-31 01:55:5768#include "chrome/browser/extensions/permissions_updater.h"
Oleg Davydov6541a64f2019-04-17 13:17:3369#include "chrome/browser/extensions/plugin_manager.h"
[email protected]f71b582c2014-01-10 17:03:1570#include "chrome/browser/extensions/test_blacklist.h"
[email protected]31d8f5f22012-04-02 15:22:0871#include "chrome/browser/extensions/test_extension_system.h"
[email protected]d8c8f25f2011-11-02 18:18:0172#include "chrome/browser/extensions/unpacked_installer.h"
[email protected]42a08162012-03-16 18:09:1173#include "chrome/browser/extensions/updater/extension_updater.h"
dpolukhin1687ef32015-06-22 11:12:3774#include "chrome/browser/policy/profile_policy_connector.h"
lazyboy1899eec42016-03-08 19:00:5075#include "chrome/browser/ui/global_error/global_error.h"
76#include "chrome/browser/ui/global_error/global_error_service.h"
77#include "chrome/browser/ui/global_error/global_error_service_factory.h"
Evan Stade2ec8dd82019-06-25 17:53:2178#include "chrome/browser/ui/global_error/global_error_waiter.h"
[email protected]31d8f5f22012-04-02 15:22:0879#include "chrome/common/chrome_constants.h"
[email protected]37858e52010-08-26 00:22:0280#include "chrome/common/chrome_switches.h"
[email protected]6b414c232013-06-05 07:53:3481#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
[email protected]36a784c2009-06-23 06:21:0882#include "chrome/common/pref_names.h"
[email protected]24b538a2010-02-27 01:22:4483#include "chrome/common/url_constants.h"
thestig4a9b0ef2016-08-29 08:22:1284#include "chrome/grit/browser_resources.h"
85#include "chrome/grit/generated_resources.h"
[email protected]078c3192013-08-22 08:18:0586#include "chrome/test/base/scoped_browser_locale.h"
[email protected]a4ff9eae2011-08-01 19:58:1687#include "chrome/test/base/testing_profile.h"
[email protected]fdd28372014-08-21 02:27:2688#include "components/crx_file/id_util.h"
[email protected]f0c8c4992014-05-15 17:37:2689#include "components/pref_registry/pref_registry_syncable.h"
brettwb1fc1b82016-02-02 00:19:0890#include "components/prefs/scoped_user_pref_update.h"
Nico Weberbc5b06f2019-07-26 14:00:1391#include "components/safe_browsing/buildflags.h"
skym71603842016-10-10 18:17:3192#include "components/sync/model/string_ordinal.h"
maxbogueea16ff412016-10-28 16:35:2993#include "components/sync_preferences/pref_service_syncable.h"
94#include "components/sync_preferences/testing_pref_service_syncable.h"
[email protected]35cc399e2012-02-23 18:19:2895#include "content/public/browser/dom_storage_context.h"
[email protected]98270432012-09-11 20:51:2496#include "content/public/browser/gpu_data_manager.h"
[email protected]35cc399e2012-02-23 18:19:2897#include "content/public/browser/indexed_db_context.h"
[email protected]ad50def52011-10-19 23:17:0798#include "content/public/browser/notification_service.h"
[email protected]e67385f2011-12-21 06:00:5699#include "content/public/browser/plugin_service.h"
[email protected]6d057a0c2013-07-09 21:12:07100#include "content/public/browser/render_process_host.h"
[email protected]5c8e67c2012-08-29 00:48:52101#include "content/public/browser/storage_partition.h"
[email protected]55eb70e762012-02-20 17:38:39102#include "content/public/common/content_constants.h"
Gabriel Charettec7108742019-08-23 03:31:40103#include "content/public/test/browser_task_environment.h"
[email protected]6d057a0c2013-07-09 21:12:07104#include "content/public/test/test_utils.h"
Devlin Croninbffe949eb2018-01-12 03:03:40105#include "extensions/browser/disable_reason.h"
Devlin Cronin420995d2018-01-22 20:54:06106#include "extensions/browser/extension_creator.h"
binjin47947f842014-11-18 12:10:24107#include "extensions/browser/extension_prefs.h"
[email protected]5fdfa562013-12-27 17:43:59108#include "extensions/browser/extension_registry.h"
[email protected]59b0e602014-01-30 00:41:24109#include "extensions/browser/extension_system.h"
karandeepb810e33402017-04-05 23:41:22110#include "extensions/browser/extension_util.h"
lazyboye8634172016-01-28 00:10:48111#include "extensions/browser/external_install_info.h"
[email protected]301116c62013-11-26 10:37:45112#include "extensions/browser/external_provider_interface.h"
[email protected]4a1d9c0d2014-06-13 12:50:11113#include "extensions/browser/install_flag.h"
[email protected]301116c62013-11-26 10:37:45114#include "extensions/browser/management_policy.h"
lazyboya00eafc2017-04-08 00:57:19115#include "extensions/browser/mock_external_provider.h"
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:56116#include "extensions/browser/pref_names.h"
limasdfe1d046f2015-10-29 00:48:00117#include "extensions/browser/test_extension_registry_observer.h"
[email protected]301116c62013-11-26 10:37:45118#include "extensions/browser/test_management_policy.h"
[email protected]e43c61f2014-07-20 21:46:34119#include "extensions/browser/uninstall_reason.h"
Oleg Davydov6541a64f2019-04-17 13:17:33120#include "extensions/browser/updater/extension_downloader_test_helper.h"
121#include "extensions/browser/updater/null_extension_cache.h"
[email protected]e4452d32013-11-15 23:07:41122#include "extensions/common/extension.h"
[email protected]22b7b2c2013-11-05 22:52:42123#include "extensions/common/extension_builder.h"
[email protected]6668e5d2014-04-08 23:32:52124#include "extensions/common/extension_l10n_util.h"
[email protected]993da5e2013-03-23 21:25:16125#include "extensions/common/extension_resource.h"
Oleg Davydov6541a64f2019-04-17 13:17:33126#include "extensions/common/extension_urls.h"
Karan Bhatiafe12281a2017-09-16 02:38:18127#include "extensions/common/file_util.h"
[email protected]0c3c9732013-09-16 08:53:41128#include "extensions/common/manifest_constants.h"
[email protected]558878cc82013-11-09 01:25:51129#include "extensions/common/manifest_handlers/background_info.h"
Albert Chaulkb96abb852018-03-02 00:53:13130#include "extensions/common/manifest_handlers/content_scripts_handler.h"
binjine6b58b52014-10-31 01:55:57131#include "extensions/common/manifest_handlers/permissions_parser.h"
rockotd5546142014-10-15 00:29:08132#include "extensions/common/manifest_url_handlers.h"
[email protected]5a55f3f2013-10-29 01:08:29133#include "extensions/common/permissions/permission_set.h"
[email protected]076ebeda2014-06-06 21:47:26134#include "extensions/common/permissions/permissions_data.h"
[email protected]a612eb32014-03-31 22:09:17135#include "extensions/common/switches.h"
[email protected]885c0e92012-11-13 20:27:42136#include "extensions/common/url_pattern.h"
[email protected]22b7b2c2013-11-05 22:52:42137#include "extensions/common/value_builder.h"
Joshua Pawlickifd01b7c2019-01-17 16:18:34138#include "extensions/common/verifier_formats.h"
Devlin Cronin4f455a22018-01-25 01:36:45139#include "extensions/test/test_extension_dir.h"
Julie Jeongeun Kimc0827552019-08-27 03:19:37140#include "mojo/public/cpp/bindings/remote.h"
Randy Smithe93faff2017-12-22 14:28:52141#include "net/cookies/canonical_cookie.h"
[email protected]aa84a7e2012-03-15 21:29:06142#include "net/cookies/cookie_options.h"
mmenkee28c9aa2016-01-20 23:54:04143#include "net/cookies/cookie_store.h"
Lily Chenf068a762019-08-21 21:10:50144#include "net/cookies/cookie_util.h"
[email protected]dbbad7a2010-08-13 18:18:36145#include "net/url_request/url_request_context.h"
[email protected]abe2c032011-03-31 18:49:34146#include "net/url_request/url_request_context_getter.h"
Scott Violet02e38b92018-03-27 23:42:14147#include "ppapi/buildflags/buildflags.h"
Ken Rockot54311e62018-02-10 19:01:52148#include "services/network/public/mojom/cookie_manager.mojom.h"
149#include "services/network/public/mojom/network_service.mojom.h"
pilgrime92c5fcd2014-09-10 23:31:23150#include "storage/browser/database/database_tracker.h"
151#include "storage/browser/quota/quota_manager.h"
pilgrim16330552014-09-10 01:32:22152#include "storage/common/database/database_identifier.h"
treib9afc6212015-10-30 18:49:58153#include "testing/gmock/include/gmock/gmock.h"
[email protected]6014d672008-12-05 00:38:25154#include "testing/gtest/include/gtest/gtest.h"
[email protected]f66c110c2008-12-05 20:26:29155#include "testing/platform_test.h"
fatalerr2443c2df2014-10-31 19:14:35156#include "ui/base/l10n/l10n_util.h"
[email protected]a6483d22013-07-03 22:11:00157#include "url/gurl.h"
Zhuoyu Qian492f36e52018-12-07 18:32:24158#include "url/origin.h"
[email protected]6014d672008-12-05 00:38:25159
nparker333f169b2015-04-18 13:33:07160// The blacklist tests rely on the safe-browsing database.
Nico Weberbc5b06f2019-07-26 14:00:13161#if BUILDFLAG(SAFE_BROWSING_DB_LOCAL)
[email protected]3f2a2fa2013-09-24 02:55:25162#define ENABLE_BLACKLIST_TESTS
163#endif
164
[email protected]55eb70e762012-02-20 17:38:39165using content::BrowserContext;
[email protected]631bb742011-11-02 11:29:39166using content::BrowserThread;
[email protected]35cc399e2012-02-23 18:19:28167using content::DOMStorageContext;
168using content::IndexedDBContext;
[email protected]e67385f2011-12-21 06:00:56169using content::PluginService;
[email protected]631bb742011-11-02 11:29:39170
Devlin Cronineea1b7a2018-05-26 02:46:21171namespace extensions {
172
173namespace keys = manifest_keys;
[email protected]c6d474f82009-12-16 21:11:06174
[email protected]f0397fa2008-12-11 17:59:58175namespace {
176
[email protected]df4956e2009-06-10 16:53:42177// Extension ids used during testing.
[email protected]095ccbe42013-09-26 00:06:42178const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
179const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
180const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
[email protected]aa5219d2013-11-09 19:25:41181const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
Joshua Pawlickif2f37f32018-11-05 21:40:56182const char good2048[] = "dfhpodpjggiioolfhoimofdbfjibmedp";
[email protected]095ccbe42013-09-26 00:06:42183const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
lazyboy0b9b30f2016-01-05 03:15:37184const char minimal_platform_app_crx[] = "jjeoclcdfjddkdjokiejckgcildcflpp";
[email protected]095ccbe42013-09-26 00:06:42185const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
Devlin Cronin077ce1f2018-04-25 21:18:55186const char page_action[] = "dpfmafkdlbmopmcepgpjkpldjbghdibm";
Joshua Pawlickif2f37f32018-11-05 21:40:56187const char theme_crx[] = "idlfhncioikpdnlhnmcjogambnefbbfp";
188const char theme2_crx[] = "ibcijncamhmjjdodjamgiipcgnnaeagd";
[email protected]095ccbe42013-09-26 00:06:42189const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
[email protected]095ccbe42013-09-26 00:06:42190const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
lazyboy1899eec42016-03-08 19:00:50191const char updates_from_webstore2[] = "oolblhbomdbcpmafphaodhjfcgbihcdg";
192const char updates_from_webstore3[] = "bmfoocgfinpmkmlbjhcbofejhkhlbchk";
binjine6b58b52014-10-31 01:55:57193const char permissions_blocklist[] = "noffkehfcaggllbcojjbopcmlhcnhcdn";
Takumi Fujimoto43c8c00f2017-07-26 22:48:56194const char cast_stable[] = "boadgeojelhgndaghljhdicfkmllpafd";
195const char cast_beta[] = "dliochdbjfkdbacpmhlcpmleaejidimm";
[email protected]df4956e2009-06-10 16:53:42196
lazyboy1899eec42016-03-08 19:00:50197struct BubbleErrorsTestData {
198 BubbleErrorsTestData(const std::string& id,
199 const std::string& version,
200 const base::FilePath& crx_path,
201 size_t expected_bubble_error_count)
202 : id(id),
203 version(version),
204 crx_path(crx_path),
205 expected_bubble_error_count(expected_bubble_error_count) {}
206 std::string id;
207 std::string version;
208 base::FilePath crx_path;
209 size_t expected_bubble_error_count;
210 bool expect_has_shown_bubble_view;
211};
212
[email protected]cced75a2011-05-20 08:31:12213static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
[email protected]8d888c12010-11-30 00:00:25214 int schemes = URLPattern::SCHEME_ALL;
215 extent->AddPattern(URLPattern(schemes, pattern));
216}
217
[email protected]650b2d52013-02-10 03:41:45218base::FilePath GetTemporaryFile() {
219 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:52220 CHECK(base::CreateTemporaryFile(&temp_file));
[email protected]a17dfcf2012-12-30 02:07:09221 return temp_file;
222}
223
[email protected]6d057a0c2013-07-09 21:12:07224bool WaitForCountNotificationsCallback(int *count) {
225 return --(*count) == 0;
226}
227
lazyboy0b9b30f2016-01-05 03:15:37228bool HasExternalInstallErrors(ExtensionService* service) {
229 return !service->external_install_manager()->GetErrorsForTesting().empty();
230}
231
232bool HasExternalInstallBubble(ExtensionService* service) {
233 std::vector<ExternalInstallError*> errors =
234 service->external_install_manager()->GetErrorsForTesting();
235 auto found = std::find_if(
236 errors.begin(), errors.end(),
237 [](const ExternalInstallError* error) {
238 return error->alert_type() == ExternalInstallError::BUBBLE_ALERT;
239 });
240 return found != errors.end();
241}
242
lazyboy1899eec42016-03-08 19:00:50243size_t GetExternalInstallBubbleCount(ExtensionService* service) {
244 size_t bubble_count = 0u;
245 std::vector<ExternalInstallError*> errors =
246 service->external_install_manager()->GetErrorsForTesting();
vmpstrae72b082016-07-25 21:55:47247 for (auto* error : errors)
lazyboy1899eec42016-03-08 19:00:50248 bubble_count += error->alert_type() == ExternalInstallError::BUBBLE_ALERT;
249 return bubble_count;
250}
251
Devlin Cronin8e5892f2018-10-04 00:13:43252scoped_refptr<const Extension> CreateExtension(const std::string& name,
253 const base::FilePath& path,
254 Manifest::Location location) {
Devlin Cronin077ce1f2018-04-25 21:18:55255 return ExtensionBuilder(name).SetPath(path).SetLocation(location).Build();
mtomasz622f70d22017-01-27 03:36:26256}
257
lazyboy8a08c9d2017-04-11 19:53:22258std::unique_ptr<ExternalInstallInfoFile> CreateExternalExtension(
Devlin Cronineea1b7a2018-05-26 02:46:21259 const ExtensionId& extension_id,
lazyboy8a08c9d2017-04-11 19:53:22260 const std::string& version_str,
261 const base::FilePath& path,
262 Manifest::Location location,
263 Extension::InitFromValueFlags flags) {
Jinho Bangb5216cec2018-01-17 19:43:11264 return std::make_unique<ExternalInstallInfoFile>(
Devlin Cronind4c2a8f32017-09-29 17:08:30265 extension_id, base::Version(version_str), path, location, flags, false,
266 false);
lazyboy8a08c9d2017-04-11 19:53:22267}
268
Karan Bhatiafe12281a2017-09-16 02:38:18269// Helper function to persist the passed directories and file paths in
270// |extension_dir|. Also, writes a generic manifest file.
271void PersistExtensionWithPaths(
272 const base::FilePath& extension_dir,
273 const std::vector<base::FilePath>& directory_paths,
274 const std::vector<base::FilePath>& file_paths) {
275 for (const auto& directory : directory_paths)
276 EXPECT_TRUE(base::CreateDirectory(directory));
277
278 std::string data = "file_data";
279 for (const auto& file : file_paths) {
280 EXPECT_EQ(static_cast<int>(data.size()),
281 base::WriteFile(file, data.c_str(), data.size()));
282 }
283
284 std::unique_ptr<base::DictionaryValue> manifest =
Devlin Cronineea1b7a2018-05-26 02:46:21285 DictionaryBuilder()
Karan Bhatiafe12281a2017-09-16 02:38:18286 .Set(keys::kName, "Test extension")
287 .Set(keys::kVersion, "1.0")
288 .Set(keys::kManifestVersion, 2)
289 .Build();
290
291 // Persist manifest file.
Devlin Cronineea1b7a2018-05-26 02:46:21292 base::FilePath manifest_path = extension_dir.Append(kManifestFilename);
Karan Bhatiafe12281a2017-09-16 02:38:18293 JSONFileValueSerializer(manifest_path).Serialize(*manifest);
294 EXPECT_TRUE(base::PathExists(manifest_path));
295}
296
[email protected]f0397fa2008-12-11 17:59:58297} // namespace
[email protected]6014d672008-12-05 00:38:25298
Istiaque Ahmed2a59ae02017-08-24 04:43:26299// A simplified version of ExternalPrefLoader that loads the dictionary
300// from json data specified in a string.
301class ExternalTestingLoader : public ExternalLoader {
302 public:
303 ExternalTestingLoader(const std::string& json_data,
304 const base::FilePath& fake_base_path)
305 : fake_base_path_(fake_base_path) {
306 DCHECK_CURRENTLY_ON(BrowserThread::UI);
307 JSONStringValueDeserializer deserializer(json_data);
308 base::FilePath fake_json_path = fake_base_path.AppendASCII("fake.json");
309 testing_prefs_ = ExternalPrefLoader::ExtractExtensionPrefs(&deserializer,
310 fake_json_path);
311 }
312
313 // ExternalLoader:
314 const base::FilePath GetBaseCrxFilePath() override { return fake_base_path_; }
315
316 void StartLoading() override {
317 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Istiaque Ahmedef99c8ea2017-09-06 21:19:57318 LoadFinished(testing_prefs_->CreateDeepCopy());
Istiaque Ahmed2a59ae02017-08-24 04:43:26319 }
320
321 private:
322 friend class base::RefCountedThreadSafe<ExternalLoader>;
323
324 ~ExternalTestingLoader() override {}
325
326 base::FilePath fake_base_path_;
327 std::unique_ptr<base::DictionaryValue> testing_prefs_;
328
329 DISALLOW_COPY_AND_ASSIGN(ExternalTestingLoader);
330};
331
Devlin Cronineea1b7a2018-05-26 02:46:21332class MockProviderVisitor : public ExternalProviderInterface::VisitorInterface {
[email protected]27b985d2009-06-25 17:53:15333 public:
[email protected]f0841cd2011-01-19 15:07:24334 // The provider will return |fake_base_path| from
335 // GetBaseCrxFilePath(). User can test the behavior with
336 // and without an empty path using this parameter.
[email protected]650b2d52013-02-10 03:41:45337 explicit MockProviderVisitor(base::FilePath fake_base_path)
[email protected]f0841cd2011-01-19 15:07:24338 : ids_found_(0),
[email protected]f121003b2012-05-04 21:57:47339 fake_base_path_(fake_base_path),
340 expected_creation_flags_(Extension::NO_FLAGS) {
[email protected]19eac6d2013-05-30 06:51:03341 profile_.reset(new TestingProfile);
[email protected]f121003b2012-05-04 21:57:47342 }
343
[email protected]650b2d52013-02-10 03:41:45344 MockProviderVisitor(base::FilePath fake_base_path,
345 int expected_creation_flags)
[email protected]f121003b2012-05-04 21:57:47346 : ids_found_(0),
347 fake_base_path_(fake_base_path),
348 expected_creation_flags_(expected_creation_flags) {
dpolukhin1687ef32015-06-22 11:12:37349 profile_.reset(new TestingProfile);
[email protected]27b985d2009-06-25 17:53:15350 }
351
[email protected]683d0702010-12-06 16:25:57352 int Visit(const std::string& json_data) {
lazyboye8634172016-01-28 00:10:48353 return Visit(json_data, Manifest::EXTERNAL_PREF,
354 Manifest::EXTERNAL_PREF_DOWNLOAD);
355 }
356
357 int Visit(const std::string& json_data,
358 Manifest::Location crx_location,
359 Manifest::Location download_location) {
360 crx_location_ = crx_location;
[email protected]27b985d2009-06-25 17:53:15361 // Give the test json file to the provider for parsing.
Devlin Cronineea1b7a2018-05-26 02:46:21362 provider_.reset(new ExternalProviderImpl(
363 this, new ExternalTestingLoader(json_data, fake_base_path_),
lazyboye8634172016-01-28 00:10:48364 profile_.get(), crx_location, download_location, Extension::NO_FLAGS));
Toni Barzic87026682018-01-08 23:21:04365 if (crx_location == Manifest::EXTERNAL_REGISTRY)
366 provider_->set_allow_updates(true);
[email protected]27b985d2009-06-25 17:53:15367
368 // We also parse the file into a dictionary to compare what we get back
369 // from the provider.
lazyboye8634172016-01-28 00:10:48370 prefs_ = GetDictionaryFromJSON(json_data);
[email protected]27b985d2009-06-25 17:53:15371
372 // Reset our counter.
373 ids_found_ = 0;
[email protected]683d0702010-12-06 16:25:57374 // Ask the provider to look up all extensions and return them.
[email protected]8e4560b62011-01-14 10:09:14375 provider_->VisitRegisteredExtension();
[email protected]27b985d2009-06-25 17:53:15376
377 return ids_found_;
378 }
379
lazyboye8634172016-01-28 00:10:48380 bool OnExternalExtensionFileFound(
381 const ExternalInstallInfoFile& info) override {
382 EXPECT_EQ(expected_creation_flags_, info.creation_flags);
[email protected]1bf73cc32011-10-26 22:38:31383
[email protected]27b985d2009-06-25 17:53:15384 ++ids_found_;
[email protected]023b3d12013-12-23 18:46:49385 base::DictionaryValue* pref;
[email protected]27b985d2009-06-25 17:53:15386 // This tests is to make sure that the provider only notifies us of the
387 // values we gave it. So if the id we doesn't exist in our internal
388 // dictionary then something is wrong.
lazyboye8634172016-01-28 00:10:48389 EXPECT_TRUE(prefs_->GetDictionary(info.extension_id, &pref))
390 << "Got back ID (" << info.extension_id.c_str()
391 << ") we weren't expecting";
[email protected]27b985d2009-06-25 17:53:15392
lazyboye8634172016-01-28 00:10:48393 EXPECT_TRUE(info.path.IsAbsolute());
[email protected]f0841cd2011-01-19 15:07:24394 if (!fake_base_path_.empty())
lazyboye8634172016-01-28 00:10:48395 EXPECT_TRUE(fake_base_path_.IsParent(info.path));
[email protected]f0841cd2011-01-19 15:07:24396
[email protected]27b985d2009-06-25 17:53:15397 if (pref) {
lazyboye8634172016-01-28 00:10:48398 EXPECT_TRUE(provider_->HasExtension(info.extension_id));
[email protected]0a60a2e2010-10-25 16:15:21399
[email protected]27b985d2009-06-25 17:53:15400 // Ask provider if the extension we got back is registered.
[email protected]1d5e58b2013-01-31 08:41:40401 Manifest::Location location = Manifest::INVALID_LOCATION;
pwnallcbd73192016-08-22 18:59:17402 std::unique_ptr<base::Version> v1;
[email protected]650b2d52013-02-10 03:41:45403 base::FilePath crx_path;
[email protected]0a60a2e2010-10-25 16:15:21404
lazyboye8634172016-01-28 00:10:48405 EXPECT_TRUE(provider_->GetExtensionDetails(info.extension_id, NULL, &v1));
Devlin Cronind4c2a8f32017-09-29 17:08:30406 EXPECT_EQ(info.version.GetString(), v1->GetString());
[email protected]0a60a2e2010-10-25 16:15:21407
pwnallcbd73192016-08-22 18:59:17408 std::unique_ptr<base::Version> v2;
lazyboye8634172016-01-28 00:10:48409 EXPECT_TRUE(
410 provider_->GetExtensionDetails(info.extension_id, &location, &v2));
Devlin Cronind4c2a8f32017-09-29 17:08:30411 EXPECT_EQ(info.version.GetString(), v1->GetString());
412 EXPECT_EQ(info.version.GetString(), v2->GetString());
lazyboye8634172016-01-28 00:10:48413 EXPECT_EQ(crx_location_, location);
[email protected]27b985d2009-06-25 17:53:15414
415 // Remove it so we won't count it ever again.
lazyboye8634172016-01-28 00:10:48416 prefs_->Remove(info.extension_id, NULL);
[email protected]27b985d2009-06-25 17:53:15417 }
[email protected]9060d8b02012-01-13 02:14:30418 return true;
[email protected]27b985d2009-06-25 17:53:15419 }
420
lazyboye8634172016-01-28 00:10:48421 bool OnExternalExtensionUpdateUrlFound(
422 const ExternalInstallInfoUpdateUrl& info,
423 bool is_initial_load) override {
[email protected]8ef78fd2010-08-19 17:14:32424 ++ids_found_;
[email protected]023b3d12013-12-23 18:46:49425 base::DictionaryValue* pref;
[email protected]8ef78fd2010-08-19 17:14:32426 // This tests is to make sure that the provider only notifies us of the
427 // values we gave it. So if the id we doesn't exist in our internal
428 // dictionary then something is wrong.
lazyboye8634172016-01-28 00:10:48429 EXPECT_TRUE(prefs_->GetDictionary(info.extension_id, &pref))
430 << L"Got back ID (" << info.extension_id.c_str()
431 << ") we weren't expecting";
432 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, info.download_location);
[email protected]8ef78fd2010-08-19 17:14:32433
434 if (pref) {
lazyboye8634172016-01-28 00:10:48435 EXPECT_TRUE(provider_->HasExtension(info.extension_id));
[email protected]0a60a2e2010-10-25 16:15:21436
437 // External extensions with update URLs do not have versions.
pwnallcbd73192016-08-22 18:59:17438 std::unique_ptr<base::Version> v1;
[email protected]1d5e58b2013-01-31 08:41:40439 Manifest::Location location1 = Manifest::INVALID_LOCATION;
lazyboye8634172016-01-28 00:10:48440 EXPECT_TRUE(
441 provider_->GetExtensionDetails(info.extension_id, &location1, &v1));
[email protected]0a60a2e2010-10-25 16:15:21442 EXPECT_FALSE(v1.get());
[email protected]1d5e58b2013-01-31 08:41:40443 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
[email protected]0a60a2e2010-10-25 16:15:21444
[email protected]d8fd0fd2014-03-24 13:16:06445 std::string parsed_install_parameter;
446 pref->GetString("install_parameter", &parsed_install_parameter);
lazyboye8634172016-01-28 00:10:48447 EXPECT_EQ(parsed_install_parameter, info.install_parameter);
[email protected]d8fd0fd2014-03-24 13:16:06448
[email protected]8ef78fd2010-08-19 17:14:32449 // Remove it so we won't count it again.
lazyboye8634172016-01-28 00:10:48450 prefs_->Remove(info.extension_id, NULL);
[email protected]8ef78fd2010-08-19 17:14:32451 }
[email protected]9060d8b02012-01-13 02:14:30452 return true;
[email protected]8ef78fd2010-08-19 17:14:32453 }
454
lazyboye8634172016-01-28 00:10:48455 void OnExternalProviderUpdateComplete(
456 const ExternalProviderInterface* provider,
Devlin Cronin19f70b6a2017-10-01 04:14:05457 const std::vector<ExternalInstallInfoUpdateUrl>& update_url_extensions,
458 const std::vector<ExternalInstallInfoFile>& file_extensions,
lazyboye8634172016-01-28 00:10:48459 const std::set<std::string>& removed_extensions) override {
460 ADD_FAILURE() << "MockProviderVisitor does not provide incremental updates,"
461 " use MockUpdateProviderVisitor instead.";
462 }
463
dchengae36a4a2014-10-21 12:36:36464 void OnExternalProviderReady(
Devlin Cronineea1b7a2018-05-26 02:46:21465 const ExternalProviderInterface* provider) override {
[email protected]50067e52011-10-20 23:17:07466 EXPECT_EQ(provider, provider_.get());
467 EXPECT_TRUE(provider->IsReady());
[email protected]8e4560b62011-01-14 10:09:14468 }
469
dpolukhin2c6ef2932015-05-12 16:06:13470 Profile* profile() { return profile_.get(); }
471
lazyboye8634172016-01-28 00:10:48472 protected:
Devlin Cronineea1b7a2018-05-26 02:46:21473 std::unique_ptr<ExternalProviderImpl> provider_;
lazyboye8634172016-01-28 00:10:48474
dchengc963c7142016-04-08 03:55:22475 std::unique_ptr<base::DictionaryValue> GetDictionaryFromJSON(
lazyboye8634172016-01-28 00:10:48476 const std::string& json_data) {
477 // We also parse the file into a dictionary to compare what we get back
478 // from the provider.
479 JSONStringValueDeserializer deserializer(json_data);
dchengc963c7142016-04-08 03:55:22480 std::unique_ptr<base::Value> json_value =
481 deserializer.Deserialize(NULL, NULL);
lazyboye8634172016-01-28 00:10:48482
jdoerrie1f536b22017-10-23 17:15:11483 if (!json_value || !json_value->is_dict()) {
lazyboye8634172016-01-28 00:10:48484 ADD_FAILURE() << "Unable to deserialize json data";
dchengc963c7142016-04-08 03:55:22485 return std::unique_ptr<base::DictionaryValue>();
lazyboye8634172016-01-28 00:10:48486 } else {
487 return base::DictionaryValue::From(std::move(json_value));
488 }
489 }
490
[email protected]27b985d2009-06-25 17:53:15491 private:
492 int ids_found_;
[email protected]650b2d52013-02-10 03:41:45493 base::FilePath fake_base_path_;
[email protected]f121003b2012-05-04 21:57:47494 int expected_creation_flags_;
lazyboye8634172016-01-28 00:10:48495 Manifest::Location crx_location_;
dchengc963c7142016-04-08 03:55:22496 std::unique_ptr<base::DictionaryValue> prefs_;
497 std::unique_ptr<TestingProfile> profile_;
[email protected]27b985d2009-06-25 17:53:15498
499 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
[email protected]a1257b12009-06-12 02:51:34500};
501
lazyboye8634172016-01-28 00:10:48502// Mock provider that can simulate incremental update like
503// ExternalRegistryLoader.
504class MockUpdateProviderVisitor : public MockProviderVisitor {
505 public:
506 // The provider will return |fake_base_path| from
507 // GetBaseCrxFilePath(). User can test the behavior with
508 // and without an empty path using this parameter.
509 explicit MockUpdateProviderVisitor(base::FilePath fake_base_path)
510 : MockProviderVisitor(fake_base_path) {}
511
512 void VisitDueToUpdate(const std::string& json_data) {
513 update_url_extension_ids_.clear();
514 file_extension_ids_.clear();
515 removed_extension_ids_.clear();
516
dchengc963c7142016-04-08 03:55:22517 std::unique_ptr<base::DictionaryValue> new_prefs =
lazyboye8634172016-01-28 00:10:48518 GetDictionaryFromJSON(json_data);
519 if (!new_prefs)
520 return;
Istiaque Ahmeda7431b32017-08-20 18:33:37521 provider_->UpdatePrefs(std::move(new_prefs));
lazyboye8634172016-01-28 00:10:48522 }
523
524 void OnExternalProviderUpdateComplete(
525 const ExternalProviderInterface* provider,
Devlin Cronin19f70b6a2017-10-01 04:14:05526 const std::vector<ExternalInstallInfoUpdateUrl>& update_url_extensions,
527 const std::vector<ExternalInstallInfoFile>& file_extensions,
lazyboye8634172016-01-28 00:10:48528 const std::set<std::string>& removed_extensions) override {
lazyboy4aeef202016-09-07 21:28:59529 for (const auto& extension_info : update_url_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05530 update_url_extension_ids_.insert(extension_info.extension_id);
lazyboye8634172016-01-28 00:10:48531 EXPECT_EQ(update_url_extension_ids_.size(), update_url_extensions.size());
532
lazyboy4aeef202016-09-07 21:28:59533 for (const auto& extension_info : file_extensions)
Devlin Cronin19f70b6a2017-10-01 04:14:05534 file_extension_ids_.insert(extension_info.extension_id);
lazyboye8634172016-01-28 00:10:48535 EXPECT_EQ(file_extension_ids_.size(), file_extensions.size());
536
537 for (const auto& extension_id : removed_extensions)
538 removed_extension_ids_.insert(extension_id);
539 }
540
541 size_t GetUpdateURLExtensionCount() {
542 return update_url_extension_ids_.size();
543 }
544 size_t GetFileExtensionCount() { return file_extension_ids_.size(); }
545 size_t GetRemovedExtensionCount() { return removed_extension_ids_.size(); }
546
547 bool HasSeenUpdateWithUpdateUrl(const std::string& extension_id) {
548 return update_url_extension_ids_.count(extension_id) > 0u;
549 }
550 bool HasSeenUpdateWithFile(const std::string& extension_id) {
551 return file_extension_ids_.count(extension_id) > 0u;
552 }
553 bool HasSeenRemoval(const std::string& extension_id) {
554 return removed_extension_ids_.count(extension_id) > 0u;
555 }
556
557 private:
558 std::set<std::string> update_url_extension_ids_;
559 std::set<std::string> file_extension_ids_;
560 std::set<std::string> removed_extension_ids_;
561
562 DISALLOW_COPY_AND_ASSIGN(MockUpdateProviderVisitor);
563};
564
Devlin Cronineea1b7a2018-05-26 02:46:21565struct MockExtensionRegistryObserver : public ExtensionRegistryObserver {
Toni Barzic667db0d32018-01-09 18:00:19566 MockExtensionRegistryObserver() = default;
567 ~MockExtensionRegistryObserver() override = default;
568
Devlin Cronineea1b7a2018-05-26 02:46:21569 // ExtensionRegistryObserver:
Toni Barzic667db0d32018-01-09 18:00:19570 void OnExtensionLoaded(content::BrowserContext* browser_context,
571 const Extension* extension) override {
572 last_extension_loaded = extension->id();
573 }
574 void OnExtensionUnloaded(content::BrowserContext* browser_context,
575 const Extension* extension,
576 UnloadedExtensionReason reason) override {
577 last_extension_unloaded = extension->id();
578 }
579 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
580 const Extension* extension,
581 bool is_update,
582 const std::string& old_name) override {
583 last_extension_installed = extension->id();
584 }
585 void OnExtensionUninstalled(content::BrowserContext* browser_context,
586 const Extension* extension,
Devlin Cronineea1b7a2018-05-26 02:46:21587 UninstallReason reason) override {
Toni Barzic667db0d32018-01-09 18:00:19588 last_extension_uninstalled = extension->id();
589 }
590
591 std::string last_extension_loaded;
592 std::string last_extension_unloaded;
593 std::string last_extension_installed;
594 std::string last_extension_uninstalled;
595
596 private:
597 DISALLOW_COPY_AND_ASSIGN(MockExtensionRegistryObserver);
598};
599
Devlin Cronineea1b7a2018-05-26 02:46:21600class ExtensionServiceTest : public ExtensionServiceTestWithInstall {
[email protected]bf73f0b2010-02-10 19:26:59601 public:
Gabriel Charette4a7f5ac2017-06-14 21:54:07602 ExtensionServiceTest() = default;
wkormana08d7c02015-11-17 21:43:38603
lazyboy8a08c9d2017-04-11 19:53:22604 MockExternalProvider* AddMockExternalProvider(Manifest::Location location) {
Jinho Bangb5216cec2018-01-17 19:43:11605 auto provider = std::make_unique<MockExternalProvider>(service(), location);
lazyboy8a08c9d2017-04-11 19:53:22606 MockExternalProvider* provider_ptr = provider.get();
607 service()->AddProviderForTesting(std::move(provider));
608 return provider_ptr;
[email protected]a1257b12009-06-12 02:51:34609 }
610
rdevlin.cronine1456712016-12-29 22:47:28611 // Checks for external extensions and waits for one to complete installing.
612 void WaitForExternalExtensionInstalled() {
613 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:21614 NOTIFICATION_CRX_INSTALLER_DONE,
rdevlin.cronine1456712016-12-29 22:47:28615 content::NotificationService::AllSources());
616 service()->CheckForExternalUpdates();
617 observer.Wait();
618 }
619
[email protected]9197f3b2009-06-02 00:49:27620 protected:
lazyboya00eafc2017-04-08 00:57:19621 void TestExternalProvider(MockExternalProvider* provider,
[email protected]1d5e58b2013-01-31 08:41:40622 Manifest::Location location);
[email protected]d55e7602009-12-16 04:20:42623
binjine6b58b52014-10-31 01:55:57624 // Grants all optional permissions stated in manifest to active permission
625 // set for extension |id|.
626 void GrantAllOptionalPermissions(const std::string& id) {
627 const Extension* extension = service()->GetInstalledExtension(id);
rdevlin.cronind630c302015-09-30 20:19:33628 const PermissionSet& all_optional_permissions =
Devlin Cronineea1b7a2018-05-26 02:46:21629 PermissionsParser::GetOptionalPermissions(extension);
Takashi Toyoshima69579072018-11-19 07:10:50630 permissions_test_util::GrantOptionalPermissionsAndWaitForCompletion(
631 profile(), *extension, all_optional_permissions);
binjine6b58b52014-10-31 01:55:57632 }
633
mlerman6a37b6a42014-11-26 22:10:53634 testing::AssertionResult IsBlocked(const std::string& id) {
Devlin Cronineea1b7a2018-05-26 02:46:21635 std::unique_ptr<ExtensionSet> all_unblocked_extensions =
mlerman6a37b6a42014-11-26 22:10:53636 registry()->GenerateInstalledExtensionsSet(
637 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::BLOCKED);
rdevlin.cronin165732a42016-07-18 22:25:08638 if (all_unblocked_extensions->Contains(id))
mlerman6a37b6a42014-11-26 22:10:53639 return testing::AssertionFailure() << id << " is still unblocked!";
640 if (!registry()->blocked_extensions().Contains(id))
641 return testing::AssertionFailure() << id << " is not blocked!";
642 return testing::AssertionSuccess();
643 }
644
645 // Helper method to test that an extension moves through being blocked and
646 // unblocked as appropriate for its type.
647 void AssertExtensionBlocksAndUnblocks(
648 bool should_block, const std::string extension_id) {
649 // Assume we start in an unblocked state.
650 EXPECT_FALSE(IsBlocked(extension_id));
651
652 // Block the extensions.
653 service()->BlockAllExtensions();
Gabriel Charette01507a22017-09-27 21:30:08654 content::RunAllTasksUntilIdle();
mlerman6a37b6a42014-11-26 22:10:53655
656 if (should_block)
657 ASSERT_TRUE(IsBlocked(extension_id));
658 else
659 ASSERT_FALSE(IsBlocked(extension_id));
660
661 service()->UnblockAllExtensions();
Gabriel Charette01507a22017-09-27 21:30:08662 content::RunAllTasksUntilIdle();
mlerman6a37b6a42014-11-26 22:10:53663
664 ASSERT_FALSE(IsBlocked(extension_id));
665 }
666
[email protected]6b75ec32009-08-14 06:37:18667 bool IsPrefExist(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34668 const std::string& pref_path) {
Devlin Cronineea1b7a2018-05-26 02:46:21669 const base::DictionaryValue* dict =
670 profile()->GetPrefs()->GetDictionary(pref_names::kExtensions);
[email protected]6b75ec32009-08-14 06:37:18671 if (dict == NULL) return false;
[email protected]023b3d12013-12-23 18:46:49672 const base::DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34673 if (!dict->GetDictionary(extension_id, &pref)) {
[email protected]6b75ec32009-08-14 06:37:18674 return false;
675 }
676 if (pref == NULL) {
677 return false;
678 }
679 bool val;
680 if (!pref->GetBoolean(pref_path, &val)) {
681 return false;
682 }
683 return true;
684 }
685
[email protected]8d888c12010-11-30 00:00:25686 void SetPref(const std::string& extension_id,
687 const std::string& pref_path,
vabr9984ea62017-04-10 11:33:49688 std::unique_ptr<base::Value> value,
[email protected]8d888c12010-11-30 00:00:25689 const std::string& msg) {
Devlin Cronineea1b7a2018-05-26 02:46:21690 DictionaryPrefUpdate update(profile()->GetPrefs(), pref_names::kExtensions);
[email protected]023b3d12013-12-23 18:46:49691 base::DictionaryValue* dict = update.Get();
[email protected]8d888c12010-11-30 00:00:25692 ASSERT_TRUE(dict != NULL) << msg;
[email protected]023b3d12013-12-23 18:46:49693 base::DictionaryValue* pref = NULL;
[email protected]8d888c12010-11-30 00:00:25694 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
695 EXPECT_TRUE(pref != NULL) << msg;
vabr9984ea62017-04-10 11:33:49696 pref->Set(pref_path, std::move(value));
[email protected]8d888c12010-11-30 00:00:25697 }
698
[email protected]6b75ec32009-08-14 06:37:18699 void SetPrefInteg(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34700 const std::string& pref_path,
[email protected]6b75ec32009-08-14 06:37:18701 int value) {
[email protected]e2194742010-08-12 05:54:34702 std::string msg = " while setting: ";
703 msg += extension_id;
704 msg += " ";
[email protected]a1257b12009-06-12 02:51:34705 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34706 msg += " = ";
Raul Tambrefff51b752019-02-04 13:09:47707 msg += base::NumberToString(value);
[email protected]a1257b12009-06-12 02:51:34708
Jinho Bangb5216cec2018-01-17 19:43:11709 SetPref(extension_id, pref_path, std::make_unique<base::Value>(value), msg);
[email protected]8d888c12010-11-30 00:00:25710 }
711
712 void SetPrefBool(const std::string& extension_id,
713 const std::string& pref_path,
714 bool value) {
715 std::string msg = " while setting: ";
716 msg += extension_id + " " + pref_path;
717 msg += " = ";
718 msg += (value ? "true" : "false");
719
Jinho Bangb5216cec2018-01-17 19:43:11720 SetPref(extension_id, pref_path, std::make_unique<base::Value>(value), msg);
[email protected]8d888c12010-11-30 00:00:25721 }
722
723 void ClearPref(const std::string& extension_id,
724 const std::string& pref_path) {
725 std::string msg = " while clearing: ";
726 msg += extension_id + " " + pref_path;
727
Devlin Cronineea1b7a2018-05-26 02:46:21728 DictionaryPrefUpdate update(profile()->GetPrefs(), pref_names::kExtensions);
[email protected]023b3d12013-12-23 18:46:49729 base::DictionaryValue* dict = update.Get();
[email protected]a1257b12009-06-12 02:51:34730 ASSERT_TRUE(dict != NULL) << msg;
[email protected]023b3d12013-12-23 18:46:49731 base::DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34732 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]a1257b12009-06-12 02:51:34733 EXPECT_TRUE(pref != NULL) << msg;
[email protected]8d888c12010-11-30 00:00:25734 pref->Remove(pref_path, NULL);
735 }
736
737 void SetPrefStringSet(const std::string& extension_id,
738 const std::string& pref_path,
739 const std::set<std::string>& value) {
740 std::string msg = " while setting: ";
741 msg += extension_id + " " + pref_path;
742
Jinho Bangb5216cec2018-01-17 19:43:11743 auto list_value = std::make_unique<base::ListValue>();
jdoerrie13cd648c82018-10-02 21:21:02744 for (auto iter = value.begin(); iter != value.end(); ++iter)
dchengd9ea63862016-06-03 02:27:18745 list_value->AppendString(*iter);
[email protected]8d888c12010-11-30 00:00:25746
vabr9984ea62017-04-10 11:33:49747 SetPref(extension_id, pref_path, std::move(list_value), msg);
[email protected]a1257b12009-06-12 02:51:34748 }
749
[email protected]ebd71962012-12-20 02:56:55750 void InitPluginService() {
brettw4b461082016-11-19 18:55:16751#if BUILDFLAG(ENABLE_PLUGINS)
[email protected]ebd71962012-12-20 02:56:55752 PluginService::GetInstance()->Init();
753#endif
754 }
755
binjin1569c9b2014-09-05 13:33:18756 void InitializeEmptyExtensionServiceWithTestingPrefs() {
757 ExtensionServiceTestBase::ExtensionServiceInitParams params =
758 CreateDefaultInitParams();
759 params.pref_file = base::FilePath();
760 InitializeExtensionService(params);
761 }
762
Devlin Cronineea1b7a2018-05-26 02:46:21763 ManagementPolicy* GetManagementPolicy() {
[email protected]f484f8d52014-06-12 08:38:18764 return ExtensionSystem::Get(browser_context())->management_policy();
765 }
766
lazyboy0b9b30f2016-01-05 03:15:37767 ExternalInstallError* GetError(const std::string& extension_id) {
768 std::vector<ExternalInstallError*> errors =
769 service_->external_install_manager()->GetErrorsForTesting();
770 auto found = std::find_if(
771 errors.begin(), errors.end(),
772 [&extension_id](const ExternalInstallError* error) {
773 return error->extension_id() == extension_id;
774 });
775 return found == errors.end() ? nullptr : *found;
776 }
777
Devlin Cronineea1b7a2018-05-26 02:46:21778 typedef ExtensionManagementPrefUpdater<
maxbogueea16ff412016-10-28 16:35:29779 sync_preferences::TestingPrefServiceSyncable>
780 ManagementPrefUpdater;
[email protected]bb28e062009-02-27 17:19:18781};
[email protected]6014d672008-12-05 00:38:25782
[email protected]0349ab5d2010-08-11 21:41:57783// Receives notifications from a PackExtensionJob, indicating either that
784// packing succeeded or that there was some error.
Devlin Cronineea1b7a2018-05-26 02:46:21785class PackExtensionTestClient : public PackExtensionJob::Client {
[email protected]0349ab5d2010-08-11 21:41:57786 public:
[email protected]650b2d52013-02-10 03:41:45787 PackExtensionTestClient(const base::FilePath& expected_crx_path,
788 const base::FilePath& expected_private_key_path);
dchengae36a4a2014-10-21 12:36:36789 void OnPackSuccess(const base::FilePath& crx_path,
790 const base::FilePath& private_key_path) override;
791 void OnPackFailure(const std::string& error_message,
792 ExtensionCreator::ErrorType type) override;
[email protected]0349ab5d2010-08-11 21:41:57793
794 private:
[email protected]650b2d52013-02-10 03:41:45795 const base::FilePath expected_crx_path_;
796 const base::FilePath expected_private_key_path_;
[email protected]0349ab5d2010-08-11 21:41:57797 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
798};
799
800PackExtensionTestClient::PackExtensionTestClient(
[email protected]650b2d52013-02-10 03:41:45801 const base::FilePath& expected_crx_path,
802 const base::FilePath& expected_private_key_path)
[email protected]0349ab5d2010-08-11 21:41:57803 : expected_crx_path_(expected_crx_path),
804 expected_private_key_path_(expected_private_key_path) {}
805
806// If packing succeeded, we make sure that the package names match our
807// expectations.
[email protected]650b2d52013-02-10 03:41:45808void PackExtensionTestClient::OnPackSuccess(
809 const base::FilePath& crx_path,
810 const base::FilePath& private_key_path) {
[email protected]0349ab5d2010-08-11 21:41:57811 // We got the notification and processed it; we don't expect any further tasks
812 // to be posted to the current thread, so we should stop blocking and continue
813 // on with the rest of the test.
814 // This call to |Quit()| matches the call to |Run()| in the
815 // |PackPunctuatedExtension| test.
Gabriel Charette53a9ef812017-07-26 12:36:23816 base::RunLoop::QuitCurrentWhenIdleDeprecated();
[email protected]0349ab5d2010-08-11 21:41:57817 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
818 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
[email protected]7567484142013-07-11 17:36:07819 ASSERT_TRUE(base::PathExists(private_key_path));
[email protected]0349ab5d2010-08-11 21:41:57820}
821
822// The tests are designed so that we never expect to see a packing error.
[email protected]93d973a2012-01-08 07:38:26823void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
824 ExtensionCreator::ErrorType type) {
825 if (type == ExtensionCreator::kCRXExists)
826 FAIL() << "Packing should not fail.";
827 else
828 FAIL() << "Existing CRX should have been overwritten.";
[email protected]0349ab5d2010-08-11 21:41:57829}
830
[email protected]54cb3c92009-02-17 22:30:21831// Test loading good extensions from the profile directory.
[email protected]d9a61e12012-11-14 02:43:47832TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
[email protected]ebd71962012-12-20 02:56:55833 InitPluginService();
[email protected]3f2a2fa2013-09-24 02:55:25834 InitializeGoodInstalledExtensionService();
[email protected]f484f8d52014-06-12 08:38:18835 service()->Init();
[email protected]6014d672008-12-05 00:38:25836
avia2f4804a2015-12-24 23:11:13837 uint32_t expected_num_extensions = 3u;
[email protected]e50013c32010-08-18 21:05:24838 ASSERT_EQ(expected_num_extensions, loaded_.size());
[email protected]6014d672008-12-05 00:38:25839
[email protected]fbcc40302009-06-12 20:45:45840 EXPECT_EQ(std::string(good0), loaded_[0]->id());
[email protected]e1cec06c2008-12-18 01:22:23841 EXPECT_EQ(std::string("My extension 1"),
[email protected]894bb502009-05-21 22:39:57842 loaded_[0]->name());
[email protected]e1cec06c2008-12-18 01:22:23843 EXPECT_EQ(std::string("The first extension that I made."),
[email protected]894bb502009-05-21 22:39:57844 loaded_[0]->description());
[email protected]1d5e58b2013-01-31 08:41:40845 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
David Bertoni58c113a2019-08-02 19:53:26846 EXPECT_TRUE(registry()->GetExtensionById(loaded_[0]->id(),
847 ExtensionRegistry::ENABLED));
[email protected]f484f8d52014-06-12 08:38:18848 EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size());
[email protected]eab9b452009-01-23 20:48:59849
[email protected]25b34332009-06-05 21:53:19850 ValidatePrefKeyCount(3);
[email protected]e2194742010-08-12 05:54:34851 ValidateIntegerPref(good0, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:40852 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
[email protected]e2194742010-08-12 05:54:34853 ValidateIntegerPref(good1, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:40854 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
[email protected]e2194742010-08-12 05:54:34855 ValidateIntegerPref(good2, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:40856 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
[email protected]25b34332009-06-05 21:53:19857
[email protected]06e8b8ff2011-07-13 15:03:47858 URLPatternSet expected_patterns;
859 AddPattern(&expected_patterns, "file:///*");
860 AddPattern(&expected_patterns, "http://*.google.com/*");
861 AddPattern(&expected_patterns, "https://*.google.com/*");
[email protected]dc24976f2013-06-02 21:15:09862 const Extension* extension = loaded_[0].get();
Devlin Cronineea1b7a2018-05-26 02:46:21863 const UserScriptList& scripts =
864 ContentScriptsInfo::GetContentScripts(extension);
[email protected]e66de892009-03-20 20:38:43865 ASSERT_EQ(2u, scripts.size());
lazyboy12c77d72016-08-19 20:06:09866 EXPECT_EQ(expected_patterns, scripts[0]->url_patterns());
867 EXPECT_EQ(2u, scripts[0]->js_scripts().size());
[email protected]052c92702010-06-25 07:25:52868 ExtensionResource resource00(extension->id(),
lazyboy12c77d72016-08-19 20:06:09869 scripts[0]->js_scripts()[0]->extension_root(),
870 scripts[0]->js_scripts()[0]->relative_path());
[email protected]15476932013-04-12 05:17:15871 base::FilePath expected_path =
872 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
[email protected]a14b16b2009-10-28 12:41:29873 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
[email protected]052c92702010-06-25 07:25:52874 ExtensionResource resource01(extension->id(),
lazyboy12c77d72016-08-19 20:06:09875 scripts[0]->js_scripts()[1]->extension_root(),
876 scripts[0]->js_scripts()[1]->relative_path());
[email protected]15476932013-04-12 05:17:15877 expected_path =
878 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
[email protected]a14b16b2009-10-28 12:41:29879 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
lazyboy12c77d72016-08-19 20:06:09880 EXPECT_EQ(1u, scripts[1]->url_patterns().patterns().size());
[email protected]06e8b8ff2011-07-13 15:03:47881 EXPECT_EQ("http://*.news.com/*",
lazyboy12c77d72016-08-19 20:06:09882 scripts[1]->url_patterns().begin()->GetAsString());
[email protected]052c92702010-06-25 07:25:52883 ExtensionResource resource10(extension->id(),
lazyboy12c77d72016-08-19 20:06:09884 scripts[1]->js_scripts()[0]->extension_root(),
885 scripts[1]->js_scripts()[0]->relative_path());
[email protected]a14b16b2009-10-28 12:41:29886 expected_path =
887 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
[email protected]15476932013-04-12 05:17:15888 expected_path = base::MakeAbsoluteFilePath(expected_path);
[email protected]a14b16b2009-10-28 12:41:29889 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
[email protected]06e8b8ff2011-07-13 15:03:47890
891 expected_patterns.ClearPatterns();
892 AddPattern(&expected_patterns, "http://*.google.com/*");
893 AddPattern(&expected_patterns, "https://*.google.com/*");
[email protected]076ebeda2014-06-06 21:47:26894 EXPECT_EQ(
895 expected_patterns,
rdevlin.cronind630c302015-09-30 20:19:33896 extension->permissions_data()->active_permissions().explicit_hosts());
[email protected]6014d672008-12-05 00:38:25897
[email protected]25b34332009-06-05 21:53:19898 EXPECT_EQ(std::string(good1), loaded_[1]->id());
[email protected]894bb502009-05-21 22:39:57899 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
[email protected]007b3f82013-04-09 08:46:45900 EXPECT_EQ(std::string(), loaded_[1]->description());
[email protected]81067e02009-07-27 15:12:09901 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
Devlin Cronineea1b7a2018-05-26 02:46:21902 BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
903 EXPECT_TRUE(ContentScriptsInfo::GetContentScripts(loaded_[1].get()).empty());
[email protected]1d5e58b2013-01-31 08:41:40904 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
[email protected]b8fb3032011-04-29 18:45:56905
[email protected]e50013c32010-08-18 21:05:24906 int index = expected_num_extensions - 1;
907 EXPECT_EQ(std::string(good2), loaded_[index]->id());
908 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
[email protected]007b3f82013-04-09 08:46:45909 EXPECT_EQ(std::string(), loaded_[index]->description());
lazyboy12c77d72016-08-19 20:06:09910 EXPECT_TRUE(
Devlin Cronineea1b7a2018-05-26 02:46:21911 ContentScriptsInfo::GetContentScripts(loaded_[index].get()).empty());
[email protected]1d5e58b2013-01-31 08:41:40912 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
thestig4b36dd32014-10-31 20:30:19913}
[email protected]cc655912009-01-29 23:19:19914
[email protected]54cb3c92009-02-17 22:30:21915// Test loading bad extensions from the profile directory.
[email protected]d9a61e12012-11-14 02:43:47916TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
[email protected]c6d474f82009-12-16 21:11:06917 // Initialize the test dir with a bad Preferences/extensions.
[email protected]f484f8d52014-06-12 08:38:18918 base::FilePath source_install_dir =
919 data_dir().AppendASCII("bad").AppendASCII("Extensions");
[email protected]e96a0602014-02-15 08:27:42920 base::FilePath pref_path =
921 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
[email protected]54cb3c92009-02-17 22:30:21922
[email protected]eaa7dd182010-12-14 11:09:00923 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]54cb3c92009-02-17 22:30:21924
[email protected]f484f8d52014-06-12 08:38:18925 service()->Init();
[email protected]54cb3c92009-02-17 22:30:21926
[email protected]a9b00ac2009-06-25 21:03:23927 ASSERT_EQ(4u, GetErrors().size());
928 ASSERT_EQ(0u, loaded_.size());
[email protected]25b34332009-06-05 21:53:19929
Devlin Cronineea1b7a2018-05-26 02:46:21930 EXPECT_TRUE(base::MatchPattern(
931 base::UTF16ToUTF8(GetErrors()[0]),
fatalerr2443c2df2014-10-31 19:14:35932 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
Devlin Cronineea1b7a2018-05-26 02:46:21933 manifest_errors::kManifestUnreadable))
934 << base::UTF16ToUTF8(GetErrors()[0]);
[email protected]8d6d9ff2009-02-20 08:14:39935
Devlin Cronineea1b7a2018-05-26 02:46:21936 EXPECT_TRUE(base::MatchPattern(
937 base::UTF16ToUTF8(GetErrors()[1]),
fatalerr2443c2df2014-10-31 19:14:35938 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
Devlin Cronineea1b7a2018-05-26 02:46:21939 manifest_errors::kManifestUnreadable))
940 << base::UTF16ToUTF8(GetErrors()[1]);
[email protected]8d6d9ff2009-02-20 08:14:39941
Devlin Cronineea1b7a2018-05-26 02:46:21942 EXPECT_TRUE(base::MatchPattern(
943 base::UTF16ToUTF8(GetErrors()[2]),
fatalerr2443c2df2014-10-31 19:14:35944 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
Devlin Cronineea1b7a2018-05-26 02:46:21945 manifest_errors::kMissingFile))
946 << base::UTF16ToUTF8(GetErrors()[2]);
[email protected]a9b00ac2009-06-25 21:03:23947
Devlin Cronineea1b7a2018-05-26 02:46:21948 EXPECT_TRUE(base::MatchPattern(
949 base::UTF16ToUTF8(GetErrors()[3]),
fatalerr2443c2df2014-10-31 19:14:35950 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
Devlin Cronineea1b7a2018-05-26 02:46:21951 manifest_errors::kManifestUnreadable))
952 << base::UTF16ToUTF8(GetErrors()[3]);
thestig4b36dd32014-10-31 20:30:19953}
[email protected]54cb3c92009-02-17 22:30:21954
[email protected]9f4e4f082013-06-21 07:11:19955// Test various cases for delayed install because of missing imports.
956TEST_F(ExtensionServiceTest, PendingImports) {
957 InitPluginService();
958
[email protected]f484f8d52014-06-12 08:38:18959 base::FilePath source_install_dir =
960 data_dir().AppendASCII("pending_updates_with_imports").AppendASCII(
961 "Extensions");
[email protected]e96a0602014-02-15 08:27:42962 base::FilePath pref_path =
963 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
[email protected]9f4e4f082013-06-21 07:11:19964
965 InitializeInstalledExtensionService(pref_path, source_install_dir);
966
967 // Verify there are no pending extensions initially.
[email protected]f484f8d52014-06-12 08:38:18968 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
[email protected]9f4e4f082013-06-21 07:11:19969
[email protected]f484f8d52014-06-12 08:38:18970 service()->Init();
[email protected]9f4e4f082013-06-21 07:11:19971 // Wait for GarbageCollectExtensions task to complete.
Gabriel Charette01507a22017-09-27 21:30:08972 content::RunAllTasksUntilIdle();
[email protected]9f4e4f082013-06-21 07:11:19973
974 // These extensions are used by the extensions we test below, they must be
975 // installed.
[email protected]f484f8d52014-06-12 08:38:18976 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
[email protected]9f4e4f082013-06-21 07:11:19977 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
[email protected]f484f8d52014-06-12 08:38:18978 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
[email protected]9f4e4f082013-06-21 07:11:19979 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
980
981 // Each of these extensions should have been rejected because of dependencies
982 // that cannot be satisfied.
[email protected]f484f8d52014-06-12 08:38:18983 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
[email protected]9f4e4f082013-06-21 07:11:19984 EXPECT_FALSE(
985 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
986 EXPECT_FALSE(
987 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
988 EXPECT_FALSE(
989 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
990 EXPECT_FALSE(
991 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
992 EXPECT_FALSE(
993 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
994 EXPECT_FALSE(
995 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
996
997 // Make sure the import started for the extension with a dependency.
998 EXPECT_TRUE(
999 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1000 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1001 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1002
[email protected]f484f8d52014-06-12 08:38:181003 EXPECT_FALSE(base::PathExists(extensions_install_dir().AppendASCII(
[email protected]9f4e4f082013-06-21 07:11:191004 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1005
[email protected]f484f8d52014-06-12 08:38:181006 EXPECT_TRUE(service()->pending_extension_manager()->HasPendingExtensions());
[email protected]9f4e4f082013-06-21 07:11:191007 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
[email protected]f484f8d52014-06-12 08:38:181008 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
[email protected]9f4e4f082013-06-21 07:11:191009 // Remove it because we are not testing the pending extension manager's
1010 // ability to download and install extensions.
[email protected]f484f8d52014-06-12 08:38:181011 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
[email protected]9f4e4f082013-06-21 07:11:191012}
1013
Toni Barzic667db0d32018-01-09 18:00:191014// Tests that reloading extension with a install delayed due to pending imports
1015// reloads currently installed extension version, rather than installing the
1016// delayed install.
1017TEST_F(ExtensionServiceTest, ReloadExtensionWithPendingImports) {
1018 InitializeEmptyExtensionService();
1019
1020 // Wait for GarbageCollectExtensions task to complete.
1021 content::RunAllTasksUntilIdle();
1022
1023 const base::FilePath base_path =
1024 data_dir()
1025 .AppendASCII("pending_updates_with_imports")
1026 .AppendASCII("updated_with_imports");
1027
1028 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1029
1030 // Initially installed version - the version with no imports.
1031 const base::FilePath installed_path = base_path.AppendASCII("1.0.0");
1032
1033 // The updated version - has import that is not satisfied (due to the imported
1034 // extension not being installed).
1035 const base::FilePath updated_path = base_path.AppendASCII("2.0.0");
1036
1037 ASSERT_TRUE(base::PathExists(pem_path));
1038 ASSERT_TRUE(base::PathExists(installed_path));
1039 ASSERT_TRUE(base::PathExists(updated_path));
1040
1041 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1042
1043 // Install version 1.
1044 const Extension* extension =
1045 PackAndInstallCRX(installed_path, pem_path, INSTALL_NEW,
1046 Extension::FROM_WEBSTORE, Manifest::Location::INTERNAL);
1047 content::RunAllTasksUntilIdle();
1048 ASSERT_TRUE(extension);
1049 const std::string id = extension->id();
1050
1051 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1052 EXPECT_EQ("1.0.0", extension->VersionString());
1053
1054 // No pending extensions at this point.
1055 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
1056
1057 // Update to version 2 that adds an unsatisfied import.
1058 PackCRXAndUpdateExtension(id, updated_path, pem_path, ENABLED);
1059 content::RunAllTasksUntilIdle();
1060
1061 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1062 extension = service()->GetInstalledExtension(id);
1063 ASSERT_TRUE(extension);
1064
1065 // The extension update should be delayed at this point - the old version
1066 // should still be installed.
1067 EXPECT_EQ("1.0.0", extension->VersionString());
1068
1069 // Make sure the import started for the extension with a dependency.
1070 EXPECT_TRUE(prefs->GetDelayedInstallInfo(id));
1071 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1072 prefs->GetDelayedInstallReason(id));
1073
1074 const std::string pending_id(32, 'e');
1075 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1076
1077 MockExtensionRegistryObserver reload_observer;
1078 registry()->AddObserver(&reload_observer);
1079
1080 // Reload the extension, and verify that the installed version does not
1081 // change.
1082 service()->ReloadExtension(id);
1083 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1084 EXPECT_EQ(id, reload_observer.last_extension_loaded);
1085 EXPECT_EQ(id, reload_observer.last_extension_unloaded);
1086 registry()->RemoveObserver(&reload_observer);
1087
1088 extension = service()->GetInstalledExtension(id);
1089 ASSERT_TRUE(extension);
1090 EXPECT_EQ("1.0.0", extension->VersionString());
1091
1092 // The update should remain delayed, with the import pending.
1093 EXPECT_TRUE(prefs->GetDelayedInstallInfo(id));
1094 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1095 prefs->GetDelayedInstallReason(id));
1096
1097 // Attempt delayed installed - similar to reloading the extension, the update
1098 // should remain delayed.
1099 EXPECT_FALSE(service()->FinishDelayedInstallationIfReady(id, true));
1100
1101 extension = service()->GetInstalledExtension(id);
1102 ASSERT_TRUE(extension);
1103 EXPECT_EQ("1.0.0", extension->VersionString());
1104 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1105 prefs->GetDelayedInstallReason(id));
1106 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1107
1108 // Remove the pending install because the pending extension manager's
1109 // ability to download and install extensions is not important for this test.
1110 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
1111}
1112
rdevlin.cronin7217be52017-03-24 20:47:051113// Tests that installation fails with extensions disabled.
1114TEST_F(ExtensionServiceTest, InstallExtensionsWithExtensionsDisabled) {
1115 InitializeExtensionServiceWithExtensionsDisabled();
1116 base::FilePath path = data_dir().AppendASCII("good.crx");
1117 InstallCRX(path, INSTALL_FAILED);
1118}
1119
[email protected]d7eaf572009-07-01 21:57:001120// Test installing extensions. This test tries to install few extensions using
1121// crx files. If you need to change those crx files, feel free to repackage
1122// them, throw away the key used and change the id's above.
[email protected]d9a61e12012-11-14 02:43:471123TEST_F(ExtensionServiceTest, InstallExtension) {
[email protected]eaa7dd182010-12-14 11:09:001124 InitializeEmptyExtensionService();
[email protected]25b34332009-06-05 21:53:191125 ValidatePrefKeyCount(0);
1126
[email protected]e2eb43112009-05-29 21:19:541127 // A simple extension that should install without error.
rdevlin.cronin7217be52017-03-24 20:47:051128 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:501129 InstallCRX(path, INSTALL_NEW);
[email protected]cc655912009-01-29 23:19:191130 // TODO(erikkay): verify the contents of the installed extension.
1131
[email protected]25b34332009-06-05 21:53:191132 int pref_count = 0;
1133 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341134 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:401135 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
[email protected]25b34332009-06-05 21:53:191136
[email protected]902f7cd2009-05-22 19:02:191137 // An extension with page actions.
[email protected]f484f8d52014-06-12 08:38:181138 path = data_dir().AppendASCII("page_action.crx");
[email protected]8f512c72011-11-22 21:02:501139 InstallCRX(path, INSTALL_NEW);
[email protected]25b34332009-06-05 21:53:191140 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341141 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:401142 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
[email protected]902f7cd2009-05-22 19:02:191143
[email protected]9f1087e2009-06-15 17:29:321144 // Bad signature.
[email protected]f484f8d52014-06-12 08:38:181145 path = data_dir().AppendASCII("bad_signature.crx");
[email protected]8f512c72011-11-22 21:02:501146 InstallCRX(path, INSTALL_FAILED);
[email protected]d7eaf572009-07-01 21:57:001147 ValidatePrefKeyCount(pref_count);
[email protected]fbcc40302009-06-12 20:45:451148
[email protected]cc655912009-01-29 23:19:191149 // 0-length extension file.
[email protected]f484f8d52014-06-12 08:38:181150 path = data_dir().AppendASCII("not_an_extension.crx");
[email protected]8f512c72011-11-22 21:02:501151 InstallCRX(path, INSTALL_FAILED);
[email protected]25b34332009-06-05 21:53:191152 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:191153
1154 // Bad magic number.
[email protected]f484f8d52014-06-12 08:38:181155 path = data_dir().AppendASCII("bad_magic.crx");
[email protected]8f512c72011-11-22 21:02:501156 InstallCRX(path, INSTALL_FAILED);
[email protected]25b34332009-06-05 21:53:191157 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:191158
[email protected]622813ee02013-08-21 21:00:291159 // Packed extensions may have folders or files that have underscores.
1160 // This will only cause a warning, rather than a fatal error.
[email protected]f484f8d52014-06-12 08:38:181161 path = data_dir().AppendASCII("bad_underscore.crx");
[email protected]622813ee02013-08-21 21:00:291162 InstallCRX(path, INSTALL_NEW);
1163 ValidatePrefKeyCount(++pref_count);
[email protected]99872e32009-09-25 22:02:491164
[email protected]5fda91942013-09-24 06:47:531165 // A test for an extension with a 2048-bit public key.
[email protected]f484f8d52014-06-12 08:38:181166 path = data_dir().AppendASCII("good2048.crx");
[email protected]5fda91942013-09-24 06:47:531167 InstallCRX(path, INSTALL_NEW);
1168 ValidatePrefKeyCount(++pref_count);
1169 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1170 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1171
[email protected]cc655912009-01-29 23:19:191172 // TODO(erikkay): add more tests for many of the failure cases.
1173 // TODO(erikkay): add tests for upgrade cases.
1174}
1175
[email protected]b8e45df2014-06-11 19:32:361176// Test that correct notifications are sent to ExtensionRegistryObserver on
[email protected]0d55b9a2013-07-19 10:40:261177// extension install and uninstall.
1178TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1179 InitializeEmptyExtensionService();
1180
Devlin Cronineea1b7a2018-05-26 02:46:211181 ExtensionRegistry* registry(ExtensionRegistry::Get(profile()));
[email protected]b8e45df2014-06-11 19:32:361182 MockExtensionRegistryObserver observer;
1183 registry->AddObserver(&observer);
[email protected]0d55b9a2013-07-19 10:40:261184
1185 // A simple extension that should install without error.
1186 ASSERT_TRUE(observer.last_extension_installed.empty());
[email protected]f484f8d52014-06-12 08:38:181187 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]0d55b9a2013-07-19 10:40:261188 InstallCRX(path, INSTALL_NEW);
1189 ASSERT_EQ(good_crx, observer.last_extension_installed);
1190
1191 // Uninstall the extension.
1192 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
Devlin Cronin6fd1cd62017-12-05 19:13:571193 UninstallExtension(good_crx);
[email protected]0d55b9a2013-07-19 10:40:261194 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1195
[email protected]b8e45df2014-06-11 19:32:361196 registry->RemoveObserver(&observer);
[email protected]0d55b9a2013-07-19 10:40:261197}
1198
[email protected]1bf73cc32011-10-26 22:38:311199// Tests that flags passed to OnExternalExtensionFileFound() make it to the
1200// extension object.
[email protected]d9a61e12012-11-14 02:43:471201TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
[email protected]a12ce8b22012-01-17 18:40:531202 const char kPrefFromBookmark[] = "from_bookmark";
1203
[email protected]1bf73cc32011-10-26 22:38:311204 InitializeEmptyExtensionService();
1205
[email protected]f484f8d52014-06-12 08:38:181206 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]1bf73cc32011-10-26 22:38:311207
[email protected]a12ce8b22012-01-17 18:40:531208 // Register and install an external extension.
lazyboy8a08c9d2017-04-11 19:53:221209 std::string version_str = "1.0.0.0";
1210 std::unique_ptr<ExternalInstallInfoFile> info = CreateExternalExtension(
1211 good_crx, version_str, path, Manifest::EXTERNAL_PREF,
1212 Extension::FROM_BOOKMARK);
1213 MockExternalProvider* provider =
1214 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
1215 provider->UpdateOrAddExtension(std::move(info));
1216 WaitForExternalExtensionInstalled();
[email protected]1bf73cc32011-10-26 22:38:311217
David Bertoni58c113a2019-08-02 19:53:261218 const Extension* extension =
1219 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED);
[email protected]1bf73cc32011-10-26 22:38:311220 ASSERT_TRUE(extension);
[email protected]a12ce8b22012-01-17 18:40:531221 ASSERT_TRUE(extension->from_bookmark());
[email protected]3f2a2fa2013-09-24 02:55:251222 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
[email protected]a12ce8b22012-01-17 18:40:531223
1224 // Upgrade to version 2.0, the flag should be preserved.
[email protected]f484f8d52014-06-12 08:38:181225 path = data_dir().AppendASCII("good2.crx");
[email protected]a12ce8b22012-01-17 18:40:531226 UpdateExtension(good_crx, path, ENABLED);
[email protected]3f2a2fa2013-09-24 02:55:251227 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
David Bertoni58c113a2019-08-02 19:53:261228 extension =
1229 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED);
[email protected]a12ce8b22012-01-17 18:40:531230 ASSERT_TRUE(extension);
1231 ASSERT_TRUE(extension->from_bookmark());
[email protected]1bf73cc32011-10-26 22:38:311232}
1233
[email protected]79c833b52011-04-05 18:31:011234// Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
[email protected]d9a61e12012-11-14 02:43:471235TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
[email protected]eaa7dd182010-12-14 11:09:001236 InitializeEmptyExtensionService();
[email protected]683d0702010-12-06 16:25:571237
[email protected]f484f8d52014-06-12 08:38:181238 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]683d0702010-12-06 16:25:571239
lazyboy8a08c9d2017-04-11 19:53:221240 std::string version_str = "1.0.0.0";
[email protected]683d0702010-12-06 16:25:571241 // Install an external extension.
lazyboy8a08c9d2017-04-11 19:53:221242 std::unique_ptr<ExternalInstallInfoFile> info =
1243 CreateExternalExtension(good_crx, version_str, path,
1244 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1245 MockExternalProvider* provider =
1246 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
1247 provider->UpdateOrAddExtension(std::move(info));
1248 WaitForExternalExtensionInstalled();
[email protected]6d057a0c2013-07-09 21:12:071249
David Bertoni58c113a2019-08-02 19:53:261250 ASSERT_TRUE(
1251 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]683d0702010-12-06 16:25:571252
1253 // Uninstall it and check that its killbit gets set.
Devlin Cronin6fd1cd62017-12-05 19:13:571254 UninstallExtension(good_crx);
Devlin Cronin55fab54d2017-12-16 02:27:191255 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1256 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
[email protected]683d0702010-12-06 16:25:571257
1258 // Try to re-install it externally. This should fail because of the killbit.
lazyboy8a08c9d2017-04-11 19:53:221259 info = CreateExternalExtension(good_crx, version_str, path,
1260 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1261 provider->UpdateOrAddExtension(std::move(info));
Gabriel Charette01507a22017-09-27 21:30:081262 content::RunAllTasksUntilIdle();
David Bertoni58c113a2019-08-02 19:53:261263 ASSERT_FALSE(
1264 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
Devlin Cronin55fab54d2017-12-16 02:27:191265 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
[email protected]683d0702010-12-06 16:25:571266
lazyboy8a08c9d2017-04-11 19:53:221267 std::string newer_version = "1.0.0.1";
[email protected]683d0702010-12-06 16:25:571268 // Repeat the same thing with a newer version of the extension.
[email protected]f484f8d52014-06-12 08:38:181269 path = data_dir().AppendASCII("good2.crx");
lazyboy8a08c9d2017-04-11 19:53:221270 info = CreateExternalExtension(good_crx, newer_version, path,
1271 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1272 provider->UpdateOrAddExtension(std::move(info));
Gabriel Charette01507a22017-09-27 21:30:081273 content::RunAllTasksUntilIdle();
David Bertoni58c113a2019-08-02 19:53:261274 ASSERT_FALSE(
1275 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
Devlin Cronin55fab54d2017-12-16 02:27:191276 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
[email protected]683d0702010-12-06 16:25:571277
1278 // Try adding the same extension from an external update URL.
[email protected]f484f8d52014-06-12 08:38:181279 ASSERT_FALSE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]683d0702010-12-06 16:25:571280 good_crx,
[email protected]d8fd0fd2014-03-24 13:16:061281 std::string(),
[email protected]683d0702010-12-06 16:25:571282 GURL("http:://fake.update/url"),
[email protected]464213a2013-10-15 01:06:481283 Manifest::EXTERNAL_PREF_DOWNLOAD,
1284 Extension::NO_FLAGS,
1285 false));
[email protected]b2907fd2011-03-25 16:43:371286
emaxx6699afb682016-10-10 21:22:131287 // Installation of the same extension through the policy should be successful.
1288 ASSERT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
1289 good_crx,
1290 std::string(),
1291 GURL("http:://fake.update/url"),
1292 Manifest::EXTERNAL_POLICY_DOWNLOAD,
1293 Extension::NO_FLAGS,
1294 false));
1295 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
1296 EXPECT_TRUE(service()->pending_extension_manager()->Remove(good_crx));
1297
[email protected]f484f8d52014-06-12 08:38:181298 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
[email protected]683d0702010-12-06 16:25:571299}
1300
[email protected]0f48fca2011-05-19 18:46:351301// Test that uninstalling an external extension does not crash when
1302// the extension could not be loaded.
1303// This extension shown in preferences file requires an experimental permission.
1304// It could not be loaded without such permission.
[email protected]d9a61e12012-11-14 02:43:471305TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
[email protected]f484f8d52014-06-12 08:38:181306 base::FilePath source_install_dir =
1307 data_dir().AppendASCII("good").AppendASCII("Extensions");
[email protected]0f48fca2011-05-19 18:46:351308 // The preference contains an external extension
1309 // that requires 'experimental' permission.
[email protected]650b2d52013-02-10 03:41:451310 base::FilePath pref_path = source_install_dir
[email protected]0f48fca2011-05-19 18:46:351311 .DirName()
1312 .AppendASCII("PreferencesExperimental");
1313
1314 // Aforementioned extension will not be loaded if
1315 // there is no '--enable-experimental-extension-apis' command line flag.
1316 InitializeInstalledExtensionService(pref_path, source_install_dir);
1317
[email protected]f484f8d52014-06-12 08:38:181318 service()->Init();
[email protected]0f48fca2011-05-19 18:46:351319
1320 // Check and try to uninstall it.
1321 // If we don't check whether the extension is loaded before we uninstall it
1322 // in CheckExternalUninstall, a crash will happen here because we will get or
1323 // dereference a NULL pointer (extension) inside UninstallExtension.
lazyboya00eafc2017-04-08 00:57:191324 MockExternalProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
[email protected]f484f8d52014-06-12 08:38:181325 service()->OnExternalProviderReady(&provider);
[email protected]0f48fca2011-05-19 18:46:351326}
1327
[email protected]604322d2011-03-22 16:51:561328// Test that external extensions with incorrect IDs are not installed.
[email protected]d9a61e12012-11-14 02:43:471329TEST_F(ExtensionServiceTest, FailOnWrongId) {
[email protected]604322d2011-03-22 16:51:561330 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:181331 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]604322d2011-03-22 16:51:561332
lazyboy8a08c9d2017-04-11 19:53:221333 std::string version_str = "1.0.0.0";
[email protected]604322d2011-03-22 16:51:561334
1335 const std::string wrong_id = all_zero;
1336 const std::string correct_id = good_crx;
1337 ASSERT_NE(correct_id, wrong_id);
1338
lazyboy8a08c9d2017-04-11 19:53:221339 MockExternalProvider* provider =
1340 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
1341
[email protected]604322d2011-03-22 16:51:561342 // Install an external extension with an ID from the external
1343 // source that is not equal to the ID in the extension manifest.
lazyboy8a08c9d2017-04-11 19:53:221344 std::unique_ptr<ExternalInstallInfoFile> info =
1345 CreateExternalExtension(wrong_id, version_str, path,
1346 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1347 provider->UpdateOrAddExtension(std::move(info));
1348 WaitForExternalExtensionInstalled();
David Bertoni58c113a2019-08-02 19:53:261349 ASSERT_FALSE(
1350 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]604322d2011-03-22 16:51:561351
1352 // Try again with the right ID. Expect success.
lazyboy8a08c9d2017-04-11 19:53:221353 info = CreateExternalExtension(correct_id, version_str, path,
1354 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1355 provider->UpdateOrAddExtension(std::move(info));
1356 WaitForExternalExtensionInstalled();
David Bertoni58c113a2019-08-02 19:53:261357 ASSERT_TRUE(
1358 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]604322d2011-03-22 16:51:561359}
1360
1361// Test that external extensions with incorrect versions are not installed.
[email protected]d9a61e12012-11-14 02:43:471362TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
[email protected]604322d2011-03-22 16:51:561363 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:181364 base::FilePath path = data_dir().AppendASCII("good.crx");
lazyboy8a08c9d2017-04-11 19:53:221365 MockExternalProvider* provider =
1366 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]604322d2011-03-22 16:51:561367
1368 // Install an external extension with a version from the external
1369 // source that is not equal to the version in the extension manifest.
lazyboy8a08c9d2017-04-11 19:53:221370 std::string wrong_version_str = "1.2.3.4";
1371 std::unique_ptr<ExternalInstallInfoFile> wrong_info =
1372 CreateExternalExtension(good_crx, wrong_version_str, path,
1373 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1374 provider->UpdateOrAddExtension(std::move(wrong_info));
1375 WaitForExternalExtensionInstalled();
David Bertoni58c113a2019-08-02 19:53:261376 ASSERT_FALSE(
1377 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]604322d2011-03-22 16:51:561378
1379 // Try again with the right version. Expect success.
[email protected]f484f8d52014-06-12 08:38:181380 service()->pending_extension_manager()->Remove(good_crx);
lazyboy8a08c9d2017-04-11 19:53:221381 std::unique_ptr<ExternalInstallInfoFile> correct_info =
1382 CreateExternalExtension(good_crx, "1.0.0.0", path,
1383 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS);
1384 provider->UpdateOrAddExtension(std::move(correct_info));
1385 WaitForExternalExtensionInstalled();
David Bertoni58c113a2019-08-02 19:53:261386 ASSERT_TRUE(
1387 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]604322d2011-03-22 16:51:561388}
1389
[email protected]da0aa3b2009-12-06 21:41:031390// Install a user script (they get converted automatically to an extension)
[email protected]d9a61e12012-11-14 02:43:471391TEST_F(ExtensionServiceTest, InstallUserScript) {
[email protected]da0aa3b2009-12-06 21:41:031392 // The details of script conversion are tested elsewhere, this just tests
[email protected]eaa7dd182010-12-14 11:09:001393 // integration with ExtensionService.
1394 InitializeEmptyExtensionService();
[email protected]da0aa3b2009-12-06 21:41:031395
[email protected]f484f8d52014-06-12 08:38:181396 base::FilePath path = data_dir().AppendASCII("user_script_basic.user.js");
[email protected]da0aa3b2009-12-06 21:41:031397
[email protected]7567484142013-07-11 17:36:071398 ASSERT_TRUE(base::PathExists(path));
[email protected]f484f8d52014-06-12 08:38:181399 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
[email protected]0d3e4a22011-06-23 19:02:521400 installer->set_allow_silent_install(true);
[email protected]6dfbbf82010-03-12 23:09:161401 installer->InstallUserScript(
[email protected]da0aa3b2009-12-06 21:41:031402 path,
[email protected]6dfbbf82010-03-12 23:09:161403 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
[email protected]da0aa3b2009-12-06 21:41:031404
Gabriel Charette01507a22017-09-27 21:30:081405 content::RunAllTasksUntilIdle();
[email protected]d2065e062013-12-12 23:49:521406 std::vector<base::string16> errors = GetErrors();
[email protected]da0aa3b2009-12-06 21:41:031407 EXPECT_TRUE(installed_) << "Nothing was installed.";
[email protected]41bb80bd2013-05-03 10:56:021408 EXPECT_FALSE(was_update_) << path.value();
[email protected]da0aa3b2009-12-06 21:41:031409 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
brettwd94a22142015-07-15 05:19:261410 EXPECT_EQ(0u, errors.size())
1411 << "There were errors: "
1412 << base::JoinString(errors, base::ASCIIToUTF16(","));
David Bertoni58c113a2019-08-02 19:53:261413 EXPECT_TRUE(registry()->GetExtensionById(loaded_[0]->id(),
1414 ExtensionRegistry::ENABLED))
[email protected]f484f8d52014-06-12 08:38:181415 << path.value();
[email protected]da0aa3b2009-12-06 21:41:031416
1417 installed_ = NULL;
[email protected]41bb80bd2013-05-03 10:56:021418 was_update_ = false;
[email protected]da0aa3b2009-12-06 21:41:031419 loaded_.clear();
Devlin Cronineea1b7a2018-05-26 02:46:211420 LoadErrorReporter::GetInstance()->ClearErrors();
[email protected]da0aa3b2009-12-06 21:41:031421}
1422
[email protected]3c4abc82012-10-22 22:25:541423// Extensions don't install during shutdown.
[email protected]d9a61e12012-11-14 02:43:471424TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
[email protected]3c4abc82012-10-22 22:25:541425 InitializeEmptyExtensionService();
1426
1427 // Simulate shutdown.
[email protected]f484f8d52014-06-12 08:38:181428 service()->set_browser_terminating_for_test(true);
[email protected]3c4abc82012-10-22 22:25:541429
[email protected]f484f8d52014-06-12 08:38:181430 base::FilePath path = data_dir().AppendASCII("good.crx");
1431 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
[email protected]3c4abc82012-10-22 22:25:541432 installer->set_allow_silent_install(true);
1433 installer->InstallCrx(path);
Gabriel Charette01507a22017-09-27 21:30:081434 content::RunAllTasksUntilIdle();
[email protected]3c4abc82012-10-22 22:25:541435
1436 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1437 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1438}
1439
[email protected]8d888c12010-11-30 00:00:251440// This tests that the granted permissions preferences are correctly set when
1441// installing an extension.
[email protected]d9a61e12012-11-14 02:43:471442TEST_F(ExtensionServiceTest, GrantedPermissions) {
[email protected]eaa7dd182010-12-14 11:09:001443 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:181444 base::FilePath path = data_dir().AppendASCII("permissions");
[email protected]8d888c12010-11-30 00:00:251445
[email protected]650b2d52013-02-10 03:41:451446 base::FilePath pem_path = path.AppendASCII("unknown.pem");
[email protected]8d888c12010-11-30 00:00:251447 path = path.AppendASCII("unknown");
1448
[email protected]7567484142013-07-11 17:36:071449 ASSERT_TRUE(base::PathExists(pem_path));
1450 ASSERT_TRUE(base::PathExists(path));
[email protected]8d888c12010-11-30 00:00:251451
[email protected]f484f8d52014-06-12 08:38:181452 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
[email protected]8d888c12010-11-30 00:00:251453
[email protected]c2e66e12012-06-27 06:27:061454 APIPermissionSet expected_api_perms;
[email protected]cced75a2011-05-20 08:31:121455 URLPatternSet expected_host_perms;
[email protected]8d888c12010-11-30 00:00:251456
1457 // Make sure there aren't any granted permissions before the
1458 // extension is installed.
rdevlin.cronine2d0fd02015-09-24 22:35:491459 EXPECT_FALSE(prefs->GetGrantedPermissions(permissions_crx).get());
[email protected]8d888c12010-11-30 00:00:251460
[email protected]8f512c72011-11-22 21:02:501461 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
[email protected]8d888c12010-11-30 00:00:251462
1463 EXPECT_EQ(0u, GetErrors().size());
[email protected]f484f8d52014-06-12 08:38:181464 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]8f512c72011-11-22 21:02:501465 EXPECT_EQ(permissions_crx, extension->id());
[email protected]8d888c12010-11-30 00:00:251466
[email protected]8d888c12010-11-30 00:00:251467 // Verify that the valid API permissions have been recognized.
[email protected]c2e66e12012-06-27 06:27:061468 expected_api_perms.insert(APIPermission::kTab);
[email protected]8d888c12010-11-30 00:00:251469
1470 AddPattern(&expected_host_perms, "http://*.google.com/*");
1471 AddPattern(&expected_host_perms, "https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151472 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251473 AddPattern(&expected_host_perms, "http://www.example.com/*");
1474
dchengc963c7142016-04-08 03:55:221475 std::unique_ptr<const PermissionSet> known_perms =
rdevlin.cronine2d0fd02015-09-24 22:35:491476 prefs->GetGrantedPermissions(extension->id());
treibfef128d2016-06-02 09:14:511477 ASSERT_TRUE(known_perms.get());
[email protected]0d3e4a22011-06-23 19:02:521478 EXPECT_FALSE(known_perms->IsEmpty());
1479 EXPECT_EQ(expected_api_perms, known_perms->apis());
[email protected]06e8b8ff2011-07-13 15:03:471480 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
[email protected]8d888c12010-11-30 00:00:251481}
1482
treibfef128d2016-06-02 09:14:511483// This tests that the granted permissions preferences are correctly set when
1484// updating an extension, and the extension is disabled in case of a permission
1485// escalation.
1486TEST_F(ExtensionServiceTest, GrantedPermissionsOnUpdate) {
1487 InitializeEmptyExtensionService();
1488 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1489
1490 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1491 const base::FilePath path1 = base_path.AppendASCII("update_1");
1492 const base::FilePath path2 = base_path.AppendASCII("update_2");
1493 const base::FilePath path3 = base_path.AppendASCII("update_3");
1494 const base::FilePath path4 = base_path.AppendASCII("update_4");
treib6e51bca2016-06-15 10:26:031495 const base::FilePath path5 = base_path.AppendASCII("update_5");
treibfef128d2016-06-02 09:14:511496
1497 ASSERT_TRUE(base::PathExists(pem_path));
1498 ASSERT_TRUE(base::PathExists(path1));
1499 ASSERT_TRUE(base::PathExists(path2));
1500 ASSERT_TRUE(base::PathExists(path3));
1501 ASSERT_TRUE(base::PathExists(path4));
treib6e51bca2016-06-15 10:26:031502 ASSERT_TRUE(base::PathExists(path5));
treibfef128d2016-06-02 09:14:511503
1504 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1505
1506 // Install version 1, which has the kHistory permission.
1507 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1508 const std::string id = extension->id();
1509
1510 EXPECT_EQ(0u, GetErrors().size());
1511 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1512
1513 // Verify that the history permission has been recognized.
1514 APIPermissionSet expected_api_perms;
1515 expected_api_perms.insert(APIPermission::kHistory);
1516 {
1517 std::unique_ptr<const PermissionSet> known_perms =
1518 prefs->GetGrantedPermissions(id);
1519 ASSERT_TRUE(known_perms.get());
1520 EXPECT_EQ(expected_api_perms, known_perms->apis());
1521 }
1522
1523 // Update to version 2 that adds the kTopSites permission, which has a
1524 // separate message, but is implied by kHistory. The extension should remain
1525 // enabled.
1526 PackCRXAndUpdateExtension(id, path2, pem_path, ENABLED);
1527 extension = service()->GetInstalledExtension(id);
1528 ASSERT_TRUE(extension);
1529 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1530
1531 // The extra permission should have been granted automatically.
1532 expected_api_perms.insert(APIPermission::kTopSites);
1533 {
1534 std::unique_ptr<const PermissionSet> known_perms =
1535 prefs->GetGrantedPermissions(id);
1536 ASSERT_TRUE(known_perms.get());
1537 EXPECT_EQ(expected_api_perms, known_perms->apis());
1538 }
1539
1540 // Update to version 3 that adds the kStorage permission, which does not have
1541 // a message. The extension should remain enabled.
1542 PackCRXAndUpdateExtension(id, path3, pem_path, ENABLED);
1543 extension = service()->GetInstalledExtension(id);
1544 ASSERT_TRUE(extension);
1545 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1546
1547 // The extra permission should have been granted automatically.
1548 expected_api_perms.insert(APIPermission::kStorage);
1549 {
1550 std::unique_ptr<const PermissionSet> known_perms =
1551 prefs->GetGrantedPermissions(id);
1552 ASSERT_TRUE(known_perms.get());
1553 EXPECT_EQ(expected_api_perms, known_perms->apis());
1554 }
1555
1556 // Update to version 4 that adds the kNotifications permission, which has a
1557 // message and hence is considered a permission increase. Now the extension
1558 // should get disabled.
1559 PackCRXAndUpdateExtension(id, path4, pem_path, DISABLED);
1560 extension = service()->GetInstalledExtension(id);
1561 ASSERT_TRUE(extension);
1562 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
1563
1564 // No new permissions should have been granted.
1565 {
1566 std::unique_ptr<const PermissionSet> known_perms =
1567 prefs->GetGrantedPermissions(id);
1568 ASSERT_TRUE(known_perms.get());
1569 EXPECT_EQ(expected_api_perms, known_perms->apis());
1570 }
1571}
[email protected]be083862012-09-01 03:53:451572
treib6e51bca2016-06-15 10:26:031573TEST_F(ExtensionServiceTest, ReenableWithAllPermissionsGranted) {
1574 InitializeEmptyExtensionService();
1575 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1576
1577 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1578 const base::FilePath path1 = base_path.AppendASCII("update_1");
1579 const base::FilePath path4 = base_path.AppendASCII("update_4");
1580 const base::FilePath path5 = base_path.AppendASCII("update_5");
1581
1582 ASSERT_TRUE(base::PathExists(pem_path));
1583 ASSERT_TRUE(base::PathExists(path1));
1584 ASSERT_TRUE(base::PathExists(path4));
1585 ASSERT_TRUE(base::PathExists(path5));
1586
1587 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1588
1589 // Install version 1, which has the kHistory permission.
1590 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1591 const std::string id = extension->id();
1592
1593 EXPECT_EQ(0u, GetErrors().size());
1594 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1595
1596 // Update to version 4 that adds the kNotifications permission, which has a
1597 // message and hence is considered a permission increase. The extension
1598 // should get disabled due to a permissions increase.
1599 PackCRXAndUpdateExtension(id, path4, pem_path, DISABLED);
1600 extension = service()->GetInstalledExtension(id);
1601 ASSERT_TRUE(extension);
1602 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
Minh X. Nguyen45479012017-08-18 21:35:361603 EXPECT_TRUE(prefs->HasDisableReason(
Devlin Cronineea1b7a2018-05-26 02:46:211604 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
treib6e51bca2016-06-15 10:26:031605
1606 // Update to version 5 that removes the kNotifications permission again.
1607 // The extension should get re-enabled.
1608 PackCRXAndUpdateExtension(id, path5, pem_path, ENABLED);
1609 extension = service()->GetInstalledExtension(id);
1610 ASSERT_TRUE(extension);
1611 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1612}
1613
1614TEST_F(ExtensionServiceTest, ReenableWithAllPermissionsGrantedOnStartup) {
1615 InitializeEmptyExtensionService();
1616 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1617
1618 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1619 const base::FilePath path1 = base_path.AppendASCII("update_1");
1620
1621 ASSERT_TRUE(base::PathExists(pem_path));
1622 ASSERT_TRUE(base::PathExists(path1));
1623
1624 // Install an extension which has the kHistory permission.
1625 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1626 const std::string id = extension->id();
1627
1628 EXPECT_EQ(0u, GetErrors().size());
1629 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1630
1631 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1632
1633 // Disable the extension due to a supposed permission increase, but retain its
1634 // granted permissions.
Devlin Cronineea1b7a2018-05-26 02:46:211635 service()->DisableExtension(id, disable_reason::DISABLE_PERMISSIONS_INCREASE);
treib6e51bca2016-06-15 10:26:031636 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
Minh X. Nguyen45479012017-08-18 21:35:361637 EXPECT_TRUE(prefs->HasDisableReason(
Devlin Cronineea1b7a2018-05-26 02:46:211638 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
treib6e51bca2016-06-15 10:26:031639
1640 // Simulate a Chrome restart. Since the extension has all required
1641 // permissions, it should get re-enabled.
1642 service()->ReloadExtensionsForTest();
1643 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
Minh X. Nguyen45479012017-08-18 21:35:361644 EXPECT_FALSE(prefs->HasDisableReason(
Devlin Cronineea1b7a2018-05-26 02:46:211645 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
treib6e51bca2016-06-15 10:26:031646}
1647
1648TEST_F(ExtensionServiceTest,
1649 DontReenableWithAllPermissionsGrantedButOtherReason) {
1650 InitializeEmptyExtensionService();
1651 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1652
1653 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1654 const base::FilePath path1 = base_path.AppendASCII("update_1");
1655 const base::FilePath path4 = base_path.AppendASCII("update_4");
1656 const base::FilePath path5 = base_path.AppendASCII("update_5");
1657
1658 ASSERT_TRUE(base::PathExists(pem_path));
1659 ASSERT_TRUE(base::PathExists(path1));
1660 ASSERT_TRUE(base::PathExists(path4));
1661 ASSERT_TRUE(base::PathExists(path5));
1662
1663 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1664
1665 // Install version 1, which has the kHistory permission.
1666 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1667 const std::string id = extension->id();
1668
1669 EXPECT_EQ(0u, GetErrors().size());
1670 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1671
1672 // Disable the extension.
Devlin Cronineea1b7a2018-05-26 02:46:211673 service()->DisableExtension(id, disable_reason::DISABLE_USER_ACTION);
treib6e51bca2016-06-15 10:26:031674 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
Devlin Cronineea1b7a2018-05-26 02:46:211675 EXPECT_TRUE(prefs->HasDisableReason(id, disable_reason::DISABLE_USER_ACTION));
treib6e51bca2016-06-15 10:26:031676
1677 // Update to version 4 that adds the kNotifications permission, which has a
1678 // message and hence is considered a permission increase. The extension
1679 // should get disabled due to a permissions increase.
1680 PackCRXAndUpdateExtension(id, path4, pem_path, DISABLED);
1681 extension = service()->GetInstalledExtension(id);
1682 ASSERT_TRUE(extension);
1683 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
Minh X. Nguyen45479012017-08-18 21:35:361684 EXPECT_TRUE(prefs->HasDisableReason(
Devlin Cronineea1b7a2018-05-26 02:46:211685 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
treib6e51bca2016-06-15 10:26:031686 // The USER_ACTION reason should also still be there.
Devlin Cronineea1b7a2018-05-26 02:46:211687 EXPECT_TRUE(prefs->HasDisableReason(id, disable_reason::DISABLE_USER_ACTION));
treib6e51bca2016-06-15 10:26:031688
1689 // Update to version 5 that removes the kNotifications permission again.
1690 // The PERMISSIONS_INCREASE should be removed, but the extension should stay
1691 // disabled since USER_ACTION is still there.
1692 PackCRXAndUpdateExtension(id, path5, pem_path, DISABLED);
1693 extension = service()->GetInstalledExtension(id);
1694 ASSERT_TRUE(extension);
1695 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
Devlin Cronineea1b7a2018-05-26 02:46:211696 EXPECT_EQ(disable_reason::DISABLE_USER_ACTION, prefs->GetDisableReasons(id));
treib6e51bca2016-06-15 10:26:031697}
1698
1699TEST_F(ExtensionServiceTest,
1700 DontReenableWithAllPermissionsGrantedOnStartupButOtherReason) {
1701 InitializeEmptyExtensionService();
1702 const base::FilePath base_path = data_dir().AppendASCII("permissions");
1703
1704 const base::FilePath pem_path = base_path.AppendASCII("update.pem");
1705 const base::FilePath path1 = base_path.AppendASCII("update_1");
1706
1707 ASSERT_TRUE(base::PathExists(pem_path));
1708 ASSERT_TRUE(base::PathExists(path1));
1709
1710 // Install an extension which has the kHistory permission.
1711 const Extension* extension = PackAndInstallCRX(path1, pem_path, INSTALL_NEW);
1712 const std::string id = extension->id();
1713
1714 EXPECT_EQ(0u, GetErrors().size());
1715 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1716
1717 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1718
1719 // Disable the extension due to a supposed permission increase, but retain its
1720 // granted permissions.
Devlin Cronineea1b7a2018-05-26 02:46:211721 service()->DisableExtension(id, disable_reason::DISABLE_PERMISSIONS_INCREASE |
1722 disable_reason::DISABLE_USER_ACTION);
treib6e51bca2016-06-15 10:26:031723 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
Minh X. Nguyen45479012017-08-18 21:35:361724 EXPECT_TRUE(prefs->HasDisableReason(
Devlin Cronineea1b7a2018-05-26 02:46:211725 id, disable_reason::DISABLE_PERMISSIONS_INCREASE));
treib6e51bca2016-06-15 10:26:031726
1727 // Simulate a Chrome restart. Since the extension has all required
1728 // permissions, the DISABLE_PERMISSIONS_INCREASE should get removed, but it
1729 // should stay disabled due to the remaining DISABLE_USER_ACTION reason.
1730 service()->ReloadExtensionsForTest();
1731 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
Devlin Cronineea1b7a2018-05-26 02:46:211732 EXPECT_EQ(disable_reason::DISABLE_USER_ACTION, prefs->GetDisableReasons(id));
treib6e51bca2016-06-15 10:26:031733}
1734
Devlin Cronin3e8b40832018-05-17 22:11:551735// Tests that installing an extension with a permission adds it to the granted
1736// permissions, so that if it is later removed and then re-added the extension
1737// is not disabled.
1738TEST_F(ExtensionServiceTest,
1739 ReaddingOldPermissionInUpdateDoesntDisableExtension) {
1740 InitializeEmptyExtensionService();
1741
1742 // Borrow a PEM for consistent IDs.
1743 const base::FilePath pem_path =
1744 data_dir().AppendASCII("permissions/update.pem");
1745 ASSERT_TRUE(base::PathExists(pem_path));
1746
1747 constexpr char kManifestTemplate[] =
1748 R"({
1749 "name": "Test",
1750 "description": "Test permissions update flow",
1751 "manifest_version": 2,
1752 "version": "%s",
1753 "permissions": [%s]
1754 })";
1755
1756 // Install version 1, which includes the tabs permission.
Devlin Cronineea1b7a2018-05-26 02:46:211757 TestExtensionDir version1;
Devlin Cronin3e8b40832018-05-17 22:11:551758 version1.WriteManifest(
1759 base::StringPrintf(kManifestTemplate, "1", R"("tabs")"));
1760
1761 const Extension* extension =
1762 PackAndInstallCRX(version1.UnpackedPath(), pem_path, INSTALL_NEW);
1763 ASSERT_TRUE(extension);
1764
1765 const std::string id = extension->id();
1766
1767 EXPECT_EQ(0u, GetErrors().size());
1768 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
1769
1770 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1771
1772 auto get_granted_permissions = [prefs, id]() {
1773 return prefs->GetGrantedPermissions(id);
1774 };
1775
1776 auto get_active_permissions = [prefs, id]() {
1777 return prefs->GetActivePermissions(id);
1778 };
1779
1780 APIPermissionSet tabs_permission_set;
1781 tabs_permission_set.insert(APIPermission::kTab);
1782
1783 EXPECT_EQ(tabs_permission_set, get_granted_permissions()->apis());
1784 EXPECT_EQ(tabs_permission_set, get_active_permissions()->apis());
1785
1786 // Version 2 removes the tabs permission. The tabs permission should be
1787 // gone from the active permissions, but retained in the granted permissions.
Devlin Cronineea1b7a2018-05-26 02:46:211788 TestExtensionDir version2;
Devlin Cronin3e8b40832018-05-17 22:11:551789 version2.WriteManifest(base::StringPrintf(kManifestTemplate, "2", ""));
1790
1791 PackCRXAndUpdateExtension(id, version2.UnpackedPath(), pem_path, ENABLED);
1792 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1793
1794 EXPECT_EQ(tabs_permission_set, get_granted_permissions()->apis());
1795 EXPECT_TRUE(get_active_permissions()->IsEmpty());
1796
1797 // Version 3 re-adds the tabs permission. Even though this is an increase in
1798 // privilege from version 2, it's not from the granted permissions (which
1799 // include the permission from version 1). Therefore, the extension should
1800 // remain enabled.
Devlin Cronineea1b7a2018-05-26 02:46:211801 TestExtensionDir version3;
Devlin Cronin3e8b40832018-05-17 22:11:551802 version3.WriteManifest(
1803 base::StringPrintf(kManifestTemplate, "3", R"("tabs")"));
1804
1805 PackCRXAndUpdateExtension(id, version3.UnpackedPath(), pem_path, ENABLED);
1806 EXPECT_TRUE(registry()->enabled_extensions().Contains(id));
1807
1808 EXPECT_EQ(tabs_permission_set, get_granted_permissions()->apis());
1809 EXPECT_EQ(tabs_permission_set, get_active_permissions()->apis());
1810}
1811
[email protected]be083862012-09-01 03:53:451812#if !defined(OS_CHROMEOS)
1813// This tests that the granted permissions preferences are correctly set for
1814// default apps.
[email protected]d9a61e12012-11-14 02:43:471815TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
[email protected]be083862012-09-01 03:53:451816 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:181817 base::FilePath path = data_dir().AppendASCII("permissions");
[email protected]be083862012-09-01 03:53:451818
[email protected]650b2d52013-02-10 03:41:451819 base::FilePath pem_path = path.AppendASCII("unknown.pem");
[email protected]be083862012-09-01 03:53:451820 path = path.AppendASCII("unknown");
1821
[email protected]7567484142013-07-11 17:36:071822 ASSERT_TRUE(base::PathExists(pem_path));
1823 ASSERT_TRUE(base::PathExists(path));
[email protected]be083862012-09-01 03:53:451824
[email protected]f484f8d52014-06-12 08:38:181825 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
[email protected]be083862012-09-01 03:53:451826
1827 APIPermissionSet expected_api_perms;
1828 URLPatternSet expected_host_perms;
1829
1830 // Make sure there aren't any granted permissions before the
1831 // extension is installed.
rdevlin.cronine2d0fd02015-09-24 22:35:491832 EXPECT_FALSE(prefs->GetGrantedPermissions(permissions_crx).get());
[email protected]be083862012-09-01 03:53:451833
1834 const Extension* extension = PackAndInstallCRX(
catmullings22bc2372016-11-02 19:59:351835 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT,
1836 Manifest::Location::INTERNAL);
[email protected]be083862012-09-01 03:53:451837
1838 EXPECT_EQ(0u, GetErrors().size());
[email protected]f484f8d52014-06-12 08:38:181839 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]be083862012-09-01 03:53:451840 EXPECT_EQ(permissions_crx, extension->id());
1841
1842 // Verify that the valid API permissions have been recognized.
1843 expected_api_perms.insert(APIPermission::kTab);
1844
dchengc963c7142016-04-08 03:55:221845 std::unique_ptr<const PermissionSet> known_perms =
rdevlin.cronine2d0fd02015-09-24 22:35:491846 prefs->GetGrantedPermissions(extension->id());
[email protected]be083862012-09-01 03:53:451847 EXPECT_TRUE(known_perms.get());
1848 EXPECT_FALSE(known_perms->IsEmpty());
1849 EXPECT_EQ(expected_api_perms, known_perms->apis());
[email protected]8d888c12010-11-30 00:00:251850}
1851#endif
1852
1853// Tests that the extension is disabled when permissions are missing from
1854// the extension's granted permissions preferences. (This simulates updating
1855// the browser to a version which recognizes more permissions).
[email protected]d9a61e12012-11-14 02:43:471856TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
[email protected]eaa7dd182010-12-14 11:09:001857 InitializeEmptyExtensionService();
[email protected]8d888c12010-11-30 00:00:251858
[email protected]f484f8d52014-06-12 08:38:181859 base::FilePath path =
1860 data_dir().AppendASCII("permissions").AppendASCII("unknown");
[email protected]8d888c12010-11-30 00:00:251861
[email protected]7567484142013-07-11 17:36:071862 ASSERT_TRUE(base::PathExists(path));
[email protected]8d888c12010-11-30 00:00:251863
[email protected]8f512c72011-11-22 21:02:501864 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
[email protected]8d888c12010-11-30 00:00:251865
1866 EXPECT_EQ(0u, GetErrors().size());
[email protected]f484f8d52014-06-12 08:38:181867 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]8d888c12010-11-30 00:00:251868 std::string extension_id = extension->id();
1869
[email protected]f484f8d52014-06-12 08:38:181870 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
[email protected]8d888c12010-11-30 00:00:251871
[email protected]c2e66e12012-06-27 06:27:061872 APIPermissionSet expected_api_permissions;
[email protected]cced75a2011-05-20 08:31:121873 URLPatternSet expected_host_permissions;
[email protected]8d888c12010-11-30 00:00:251874
[email protected]c2e66e12012-06-27 06:27:061875 expected_api_permissions.insert(APIPermission::kTab);
[email protected]8d888c12010-11-30 00:00:251876 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1877 AddPattern(&expected_host_permissions, "https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151878 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251879 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1880
[email protected]8d888c12010-11-30 00:00:251881 std::set<std::string> host_permissions;
1882
1883 // Test that the extension is disabled when an API permission is missing from
1884 // the extension's granted api permissions preference. (This simulates
1885 // updating the browser to a version which recognizes a new API permission).
[email protected]0d3e4a22011-06-23 19:02:521886 SetPref(extension_id, "granted_permissions.api",
Jinho Bangb5216cec2018-01-17 19:43:111887 std::make_unique<base::ListValue>(), "granted_permissions.api");
[email protected]f484f8d52014-06-12 08:38:181888 service()->ReloadExtensionsForTest();
[email protected]8d888c12010-11-30 00:00:251889
[email protected]f484f8d52014-06-12 08:38:181890 EXPECT_EQ(1u, registry()->disabled_extensions().size());
1891 extension = registry()->disabled_extensions().begin()->get();
[email protected]8d888c12010-11-30 00:00:251892
[email protected]ad83ca242011-07-29 01:32:251893 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
[email protected]f484f8d52014-06-12 08:38:181894 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251895 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1896
1897 // Now grant and re-enable the extension, making sure the prefs are updated.
[email protected]f484f8d52014-06-12 08:38:181898 service()->GrantPermissionsAndEnableExtension(extension);
[email protected]8d888c12010-11-30 00:00:251899
[email protected]ad83ca242011-07-29 01:32:251900 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
[email protected]f484f8d52014-06-12 08:38:181901 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251902 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1903
dchengc963c7142016-04-08 03:55:221904 std::unique_ptr<const PermissionSet> current_perms =
rdevlin.cronine2d0fd02015-09-24 22:35:491905 prefs->GetGrantedPermissions(extension_id);
[email protected]0d3e4a22011-06-23 19:02:521906 ASSERT_TRUE(current_perms.get());
1907 ASSERT_FALSE(current_perms->IsEmpty());
[email protected]0d3e4a22011-06-23 19:02:521908 ASSERT_EQ(expected_api_permissions, current_perms->apis());
[email protected]06e8b8ff2011-07-13 15:03:471909 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
[email protected]8d888c12010-11-30 00:00:251910
1911 // Tests that the extension is disabled when a host permission is missing from
1912 // the extension's granted host permissions preference. (This simulates
1913 // updating the browser to a version which recognizes additional host
1914 // permissions).
[email protected]8d888c12010-11-30 00:00:251915 host_permissions.clear();
[email protected]902fd7b2011-07-27 18:42:311916 current_perms = NULL;
[email protected]8d888c12010-11-30 00:00:251917
[email protected]8d888c12010-11-30 00:00:251918 host_permissions.insert("http://*.google.com/*");
1919 host_permissions.insert("https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151920 host_permissions.insert("http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251921
Jinho Bangb5216cec2018-01-17 19:43:111922 auto api_permissions = std::make_unique<base::ListValue>();
dchengd9ea63862016-06-03 02:27:181923 api_permissions->AppendString("tabs");
vabr9984ea62017-04-10 11:33:491924 SetPref(extension_id, "granted_permissions.api", std::move(api_permissions),
1925 "granted_permissions.api");
[email protected]0d3e4a22011-06-23 19:02:521926 SetPrefStringSet(
1927 extension_id, "granted_permissions.scriptable_host", host_permissions);
[email protected]8d888c12010-11-30 00:00:251928
[email protected]f484f8d52014-06-12 08:38:181929 service()->ReloadExtensionsForTest();
[email protected]8d888c12010-11-30 00:00:251930
[email protected]f484f8d52014-06-12 08:38:181931 EXPECT_EQ(1u, registry()->disabled_extensions().size());
1932 extension = registry()->disabled_extensions().begin()->get();
[email protected]8d888c12010-11-30 00:00:251933
[email protected]ad83ca242011-07-29 01:32:251934 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
[email protected]f484f8d52014-06-12 08:38:181935 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251936 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1937
1938 // Now grant and re-enable the extension, making sure the prefs are updated.
[email protected]f484f8d52014-06-12 08:38:181939 service()->GrantPermissionsAndEnableExtension(extension);
[email protected]8d888c12010-11-30 00:00:251940
[email protected]f484f8d52014-06-12 08:38:181941 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251942 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1943
[email protected]902fd7b2011-07-27 18:42:311944 current_perms = prefs->GetGrantedPermissions(extension_id);
[email protected]0d3e4a22011-06-23 19:02:521945 ASSERT_TRUE(current_perms.get());
1946 ASSERT_FALSE(current_perms->IsEmpty());
[email protected]0d3e4a22011-06-23 19:02:521947 ASSERT_EQ(expected_api_permissions, current_perms->apis());
[email protected]06e8b8ff2011-07-13 15:03:471948 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
[email protected]8d888c12010-11-30 00:00:251949}
1950
[email protected]a17f9462009-06-09 02:56:411951// Test Packaging and installing an extension.
[email protected]d9a61e12012-11-14 02:43:471952TEST_F(ExtensionServiceTest, PackExtension) {
[email protected]eaa7dd182010-12-14 11:09:001953 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:181954 base::FilePath input_directory =
1955 data_dir()
1956 .AppendASCII("good")
1957 .AppendASCII("Extensions")
1958 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1959 .AppendASCII("1.0.0.0");
[email protected]a17f9462009-06-09 02:56:411960
[email protected]ea1a3f62012-11-16 20:34:231961 base::ScopedTempDir temp_dir;
[email protected]aca3e9b2009-11-03 01:14:211962 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:221963 base::FilePath output_directory = temp_dir.GetPath();
[email protected]aca3e9b2009-11-03 01:14:211964
[email protected]650b2d52013-02-10 03:41:451965 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1966 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
[email protected]a17f9462009-06-09 02:56:411967
dchengc963c7142016-04-08 03:55:221968 std::unique_ptr<ExtensionCreator> creator(new ExtensionCreator());
[email protected]650b2d52013-02-10 03:41:451969 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
[email protected]93d973a2012-01-08 07:38:261970 privkey_path, ExtensionCreator::kNoRunFlags));
[email protected]7567484142013-07-11 17:36:071971 ASSERT_TRUE(base::PathExists(crx_path));
1972 ASSERT_TRUE(base::PathExists(privkey_path));
[email protected]93d973a2012-01-08 07:38:261973
1974 // Repeat the run with the pem file gone, and no special flags
1975 // Should refuse to overwrite the existing crx.
[email protected]dd3aa792013-07-16 19:10:231976 base::DeleteFile(privkey_path, false);
[email protected]650b2d52013-02-10 03:41:451977 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
[email protected]93d973a2012-01-08 07:38:261978 privkey_path, ExtensionCreator::kNoRunFlags));
1979
1980 // OK, now try it with a flag to overwrite existing crx. Should work.
[email protected]650b2d52013-02-10 03:41:451981 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
[email protected]93d973a2012-01-08 07:38:261982 privkey_path, ExtensionCreator::kOverwriteCRX));
1983
1984 // Repeat the run allowing existing crx, but the existing pem is still
1985 // an error. Should fail.
[email protected]650b2d52013-02-10 03:41:451986 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
[email protected]93d973a2012-01-08 07:38:261987 privkey_path, ExtensionCreator::kOverwriteCRX));
[email protected]a17f9462009-06-09 02:56:411988
[email protected]7567484142013-07-11 17:36:071989 ASSERT_TRUE(base::PathExists(privkey_path));
[email protected]8f512c72011-11-22 21:02:501990 InstallCRX(crx_path, INSTALL_NEW);
[email protected]0dc2ca82009-11-17 07:06:161991
1992 // Try packing with invalid paths.
1993 creator.reset(new ExtensionCreator());
[email protected]650b2d52013-02-10 03:41:451994 ASSERT_FALSE(
1995 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
1996 base::FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]0dc2ca82009-11-17 07:06:161997
1998 // Try packing an empty directory. Should fail because an empty directory is
1999 // not a valid extension.
[email protected]ea1a3f62012-11-16 20:34:232000 base::ScopedTempDir temp_dir2;
[email protected]0dc2ca82009-11-17 07:06:162001 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2002 creator.reset(new ExtensionCreator());
vabr9142fe22016-09-08 13:19:222003 ASSERT_FALSE(creator->Run(temp_dir2.GetPath(), crx_path, privkey_path,
[email protected]650b2d52013-02-10 03:41:452004 base::FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]0dc2ca82009-11-17 07:06:162005
2006 // Try packing with an invalid manifest.
2007 std::string invalid_manifest_content = "I am not a manifest.";
Devlin Cronineea1b7a2018-05-26 02:46:212008 ASSERT_EQ(static_cast<int>(invalid_manifest_content.size()),
2009 base::WriteFile(temp_dir2.GetPath().Append(kManifestFilename),
2010 invalid_manifest_content.c_str(),
2011 invalid_manifest_content.size()));
[email protected]0dc2ca82009-11-17 07:06:162012 creator.reset(new ExtensionCreator());
vabr9142fe22016-09-08 13:19:222013 ASSERT_FALSE(creator->Run(temp_dir2.GetPath(), crx_path, privkey_path,
[email protected]650b2d52013-02-10 03:41:452014 base::FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]c21b5b612013-07-31 07:49:162015
2016 // Try packing with a private key that is a valid key, but invalid for the
2017 // extension.
[email protected]f484f8d52014-06-12 08:38:182018 base::FilePath bad_private_key_dir =
2019 data_dir().AppendASCII("bad_private_key");
[email protected]c21b5b612013-07-31 07:49:162020 crx_path = output_directory.AppendASCII("bad_private_key.crx");
[email protected]f484f8d52014-06-12 08:38:182021 privkey_path = data_dir().AppendASCII("bad_private_key.pem");
[email protected]c21b5b612013-07-31 07:49:162022 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2023 privkey_path, ExtensionCreator::kOverwriteCRX));
[email protected]a17f9462009-06-09 02:56:412024}
2025
[email protected]0349ab5d2010-08-11 21:41:572026// Test Packaging and installing an extension whose name contains punctuation.
[email protected]d9a61e12012-11-14 02:43:472027TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
[email protected]eaa7dd182010-12-14 11:09:002028 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182029 base::FilePath input_directory = data_dir()
2030 .AppendASCII("good")
2031 .AppendASCII("Extensions")
2032 .AppendASCII(good0)
2033 .AppendASCII("1.0.0.0");
[email protected]0349ab5d2010-08-11 21:41:572034
[email protected]ea1a3f62012-11-16 20:34:232035 base::ScopedTempDir temp_dir;
[email protected]0349ab5d2010-08-11 21:41:572036 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2037
2038 // Extension names containing punctuation, and the expected names for the
2039 // packed extensions.
[email protected]650b2d52013-02-10 03:41:452040 const base::FilePath punctuated_names[] = {
2041 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2042 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2043 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
[email protected]d9034ed22012-02-10 02:04:402044 NormalizePathSeparators(),
[email protected]0349ab5d2010-08-11 21:41:572045 };
[email protected]650b2d52013-02-10 03:41:452046 const base::FilePath expected_crx_names[] = {
2047 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2048 base::FilePath(
2049 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2050 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
[email protected]0349ab5d2010-08-11 21:41:572051 };
[email protected]650b2d52013-02-10 03:41:452052 const base::FilePath expected_private_key_names[] = {
2053 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2054 base::FilePath(
2055 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2056 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
[email protected]0349ab5d2010-08-11 21:41:572057 };
2058
Avi Drissman5f0fb8c2018-12-25 23:20:492059 for (size_t i = 0; i < base::size(punctuated_names); ++i) {
[email protected]0349ab5d2010-08-11 21:41:572060 SCOPED_TRACE(punctuated_names[i].value().c_str());
vabr9142fe22016-09-08 13:19:222061 base::FilePath output_dir = temp_dir.GetPath().Append(punctuated_names[i]);
[email protected]0349ab5d2010-08-11 21:41:572062
2063 // Copy the extension into the output directory, as PackExtensionJob doesn't
2064 // let us choose where to output the packed extension.
[email protected]f0ff2ad2013-07-09 17:42:262065 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
[email protected]0349ab5d2010-08-11 21:41:572066
[email protected]650b2d52013-02-10 03:41:452067 base::FilePath expected_crx_path =
vabr9142fe22016-09-08 13:19:222068 temp_dir.GetPath().Append(expected_crx_names[i]);
[email protected]650b2d52013-02-10 03:41:452069 base::FilePath expected_private_key_path =
vabr9142fe22016-09-08 13:19:222070 temp_dir.GetPath().Append(expected_private_key_names[i]);
[email protected]0349ab5d2010-08-11 21:41:572071 PackExtensionTestClient pack_client(expected_crx_path,
2072 expected_private_key_path);
Istiaque Ahmed6a06cc92017-08-12 00:31:332073 {
Devlin Cronineea1b7a2018-05-26 02:46:212074 PackExtensionJob packer(&pack_client, output_dir, base::FilePath(),
2075 ExtensionCreator::kOverwriteCRX);
Istiaque Ahmed6a06cc92017-08-12 00:31:332076 packer.Start();
[email protected]0349ab5d2010-08-11 21:41:572077
Istiaque Ahmed6a06cc92017-08-12 00:31:332078 // The packer will post a notification task to the current thread's
2079 // message loop when it is finished. We manually run the loop here so
2080 // that we block and catch the notification; otherwise, the process would
2081 // exit.
2082 // This call to |Run()| is matched by a call to |Quit()| in the
2083 // |PackExtensionTestClient|'s notification handling code.
2084 base::RunLoop().Run();
2085 }
[email protected]0349ab5d2010-08-11 21:41:572086
2087 if (HasFatalFailure())
2088 return;
2089
[email protected]8f512c72011-11-22 21:02:502090 InstallCRX(expected_crx_path, INSTALL_NEW);
[email protected]0349ab5d2010-08-11 21:41:572091 }
2092}
2093
[email protected]d9a61e12012-11-14 02:43:472094TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
[email protected]ab55c2b2012-06-01 23:55:032095 InitializeEmptyExtensionService();
2096
[email protected]ea1a3f62012-11-16 20:34:232097 base::ScopedTempDir extension_temp_dir;
[email protected]ab55c2b2012-06-01 23:55:032098 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:222099 base::FilePath input_directory =
2100 extension_temp_dir.GetPath().AppendASCII("ext");
[email protected]f484f8d52014-06-12 08:38:182101 ASSERT_TRUE(
2102 base::CopyDirectory(data_dir()
2103 .AppendASCII("good")
2104 .AppendASCII("Extensions")
2105 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2106 .AppendASCII("1.0.0.0"),
2107 input_directory,
2108 /*recursive=*/true));
[email protected]ab55c2b2012-06-01 23:55:032109
[email protected]ea1a3f62012-11-16 20:34:232110 base::ScopedTempDir output_temp_dir;
[email protected]ab55c2b2012-06-01 23:55:032111 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:222112 base::FilePath output_directory = output_temp_dir.GetPath();
[email protected]ab55c2b2012-06-01 23:55:032113
[email protected]650b2d52013-02-10 03:41:452114 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2115 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
[email protected]ab55c2b2012-06-01 23:55:032116
2117 // Pack the extension once to get a private key.
dchengc963c7142016-04-08 03:55:222118 std::unique_ptr<ExtensionCreator> creator(new ExtensionCreator());
[email protected]650b2d52013-02-10 03:41:452119 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
[email protected]ab55c2b2012-06-01 23:55:032120 privkey_path, ExtensionCreator::kNoRunFlags))
2121 << creator->error_message();
[email protected]7567484142013-07-11 17:36:072122 ASSERT_TRUE(base::PathExists(crx_path));
2123 ASSERT_TRUE(base::PathExists(privkey_path));
[email protected]ab55c2b2012-06-01 23:55:032124
[email protected]dd3aa792013-07-16 19:10:232125 base::DeleteFile(crx_path, false);
[email protected]ab55c2b2012-06-01 23:55:032126 // Move the pem file into the extension.
[email protected]5553d5b2013-07-01 23:07:362127 base::Move(privkey_path,
[email protected]ab55c2b2012-06-01 23:55:032128 input_directory.AppendASCII("privkey.pem"));
2129
2130 // This pack should fail because of the contained private key.
[email protected]650b2d52013-02-10 03:41:452131 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
[email protected]ab55c2b2012-06-01 23:55:032132 privkey_path, ExtensionCreator::kNoRunFlags));
2133 EXPECT_THAT(creator->error_message(),
2134 testing::ContainsRegex(
2135 "extension includes the key file.*privkey.pem"));
2136}
2137
[email protected]a17f9462009-06-09 02:56:412138// Test Packaging and installing an extension using an openssl generated key.
2139// The openssl is generated with the following:
[email protected]a1257b12009-06-12 02:51:342140// > openssl genrsa -out privkey.pem 1024
[email protected]df4956e2009-06-10 16:53:422141// > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
[email protected]a1257b12009-06-12 02:51:342142// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
[email protected]a17f9462009-06-09 02:56:412143// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
[email protected]d9a61e12012-11-14 02:43:472144TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
[email protected]eaa7dd182010-12-14 11:09:002145 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182146 base::FilePath input_directory =
2147 data_dir()
2148 .AppendASCII("good")
2149 .AppendASCII("Extensions")
2150 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2151 .AppendASCII("1.0.0.0");
2152 base::FilePath privkey_path(
2153 data_dir().AppendASCII("openssl_privkey_asn1.pem"));
[email protected]7567484142013-07-11 17:36:072154 ASSERT_TRUE(base::PathExists(privkey_path));
[email protected]a17f9462009-06-09 02:56:412155
[email protected]ea1a3f62012-11-16 20:34:232156 base::ScopedTempDir temp_dir;
[email protected]aca3e9b2009-11-03 01:14:212157 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:222158 base::FilePath output_directory = temp_dir.GetPath();
[email protected]aca3e9b2009-11-03 01:14:212159
[email protected]650b2d52013-02-10 03:41:452160 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
[email protected]a17f9462009-06-09 02:56:412161
dchengc963c7142016-04-08 03:55:222162 std::unique_ptr<ExtensionCreator> creator(new ExtensionCreator());
[email protected]a17f9462009-06-09 02:56:412163 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
[email protected]650b2d52013-02-10 03:41:452164 base::FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]a17f9462009-06-09 02:56:412165
[email protected]8f512c72011-11-22 21:02:502166 InstallCRX(crx_path, INSTALL_NEW);
[email protected]a17f9462009-06-09 02:56:412167}
[email protected]a17f9462009-06-09 02:56:412168
rdevlin.cronin7217be52017-03-24 20:47:052169TEST_F(ExtensionServiceTest, TestInstallThemeWithExtensionsDisabled) {
2170 // Themes can be installed, even when extensions are disabled.
2171 InitializeExtensionServiceWithExtensionsDisabled();
2172 base::FilePath path = data_dir().AppendASCII("theme.crx");
2173 InstallCRX(path, INSTALL_NEW);
2174 ValidatePrefKeyCount(1);
2175 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2176 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2177}
2178
[email protected]87065922014-05-28 14:50:372179#if defined(THREAD_SANITIZER)
2180// Flaky under Tsan. http://crbug.com/377702
2181#define MAYBE_InstallTheme DISABLED_InstallTheme
2182#else
2183#define MAYBE_InstallTheme InstallTheme
2184#endif
2185
2186TEST_F(ExtensionServiceTest, MAYBE_InstallTheme) {
[email protected]eaa7dd182010-12-14 11:09:002187 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182188 service()->Init();
[email protected]e2eb43112009-05-29 21:19:542189
2190 // A theme.
[email protected]f484f8d52014-06-12 08:38:182191 base::FilePath path = data_dir().AppendASCII("theme.crx");
[email protected]8f512c72011-11-22 21:02:502192 InstallCRX(path, INSTALL_NEW);
[email protected]25b34332009-06-05 21:53:192193 int pref_count = 0;
2194 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:342195 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:402196 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
[email protected]e2eb43112009-05-29 21:19:542197
[email protected]f484f8d52014-06-12 08:38:182198 path = data_dir().AppendASCII("theme2.crx");
[email protected]8f512c72011-11-22 21:02:502199 InstallCRX(path, INSTALL_NEW);
[email protected]25b34332009-06-05 21:53:192200 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:342201 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:402202 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
[email protected]494c06e2009-07-25 01:06:422203
[email protected]f6dec1e322012-04-30 21:04:512204 // A theme with extension elements. Themes cannot have extension elements,
2205 // so any such elements (like content scripts) should be ignored.
[email protected]f6dec1e322012-04-30 21:04:512206 {
[email protected]f484f8d52014-06-12 08:38:182207 path = data_dir().AppendASCII("theme_with_extension.crx");
[email protected]f6dec1e322012-04-30 21:04:512208 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2209 ValidatePrefKeyCount(++pref_count);
2210 ASSERT_TRUE(extension);
2211 EXPECT_TRUE(extension->is_theme());
Devlin Cronineea1b7a2018-05-26 02:46:212212 EXPECT_TRUE(ContentScriptsInfo::GetContentScripts(extension).empty());
[email protected]f6dec1e322012-04-30 21:04:512213 }
[email protected]12198912009-06-05 03:41:222214
2215 // A theme with image resources missing (misspelt path).
[email protected]f484f8d52014-06-12 08:38:182216 path = data_dir().AppendASCII("theme_missing_image.crx");
[email protected]8f512c72011-11-22 21:02:502217 InstallCRX(path, INSTALL_FAILED);
[email protected]25b34332009-06-05 21:53:192218 ValidatePrefKeyCount(pref_count);
[email protected]e2eb43112009-05-29 21:19:542219}
2220
[email protected]d9a61e12012-11-14 02:43:472221TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
[email protected]584245e52010-06-17 01:08:132222 // Load.
[email protected]eaa7dd182010-12-14 11:09:002223 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182224 service()->Init();
[email protected]b1ac70462013-08-14 21:33:302225
[email protected]f484f8d52014-06-12 08:38:182226 base::FilePath extension_path = data_dir().AppendASCII("theme_i18n");
[email protected]584245e52010-06-17 01:08:132227
Devlin Cronineea1b7a2018-05-26 02:46:212228 UnpackedInstaller::Create(service())->Load(extension_path);
Gabriel Charette01507a22017-09-27 21:30:082229 content::RunAllTasksUntilIdle();
[email protected]584245e52010-06-17 01:08:132230 EXPECT_EQ(0u, GetErrors().size());
2231 ASSERT_EQ(1u, loaded_.size());
[email protected]f484f8d52014-06-12 08:38:182232 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2233 const Extension* theme = registry()->enabled_extensions().begin()->get();
[email protected]8f512c72011-11-22 21:02:502234 EXPECT_EQ("name", theme->name());
2235 EXPECT_EQ("description", theme->description());
[email protected]a17dfcf2012-12-30 02:07:092236
estadeb8867dff2016-11-03 17:33:332237 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
[email protected]a17dfcf2012-12-30 02:07:092238 // temporary directory, but it automatically installs to the extension's
2239 // directory, and we don't want to copy the whole extension for a unittest.
estadeb8867dff2016-11-03 17:33:332240 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
[email protected]7567484142013-07-11 17:36:072241 ASSERT_TRUE(base::PathExists(theme_file));
[email protected]dd3aa792013-07-16 19:10:232242 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive.
[email protected]584245e52010-06-17 01:08:132243}
2244
[email protected]91236521162012-05-24 15:02:512245#if defined(OS_POSIX)
[email protected]d9a61e12012-11-14 02:43:472246TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
[email protected]f484f8d52014-06-12 08:38:182247 base::FilePath source_data_dir =
2248 data_dir().AppendASCII("unpacked").AppendASCII("symlinks_allowed");
[email protected]91236521162012-05-24 15:02:512249
2250 // Paths to test data files.
[email protected]650b2d52013-02-10 03:41:452251 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
[email protected]7567484142013-07-11 17:36:072252 ASSERT_TRUE(base::PathExists(source_manifest));
[email protected]650b2d52013-02-10 03:41:452253 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
[email protected]7567484142013-07-11 17:36:072254 ASSERT_TRUE(base::PathExists(source_icon));
[email protected]91236521162012-05-24 15:02:512255
2256 // Set up the temporary extension directory.
[email protected]ea1a3f62012-11-16 20:34:232257 base::ScopedTempDir temp;
[email protected]91236521162012-05-24 15:02:512258 ASSERT_TRUE(temp.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:222259 base::FilePath extension_path = temp.GetPath();
Devlin Cronineea1b7a2018-05-26 02:46:212260 base::FilePath manifest = extension_path.Append(kManifestFilename);
[email protected]650b2d52013-02-10 03:41:452261 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
[email protected]f0ff2ad2013-07-09 17:42:262262 base::CopyFile(source_manifest, manifest);
[email protected]b264eab2013-11-27 23:22:082263 base::CreateSymbolicLink(source_icon, icon_symlink);
[email protected]91236521162012-05-24 15:02:512264
2265 // Load extension.
2266 InitializeEmptyExtensionService();
Devlin Cronineea1b7a2018-05-26 02:46:212267 UnpackedInstaller::Create(service())->Load(extension_path);
Gabriel Charette01507a22017-09-27 21:30:082268 content::RunAllTasksUntilIdle();
[email protected]91236521162012-05-24 15:02:512269
2270 EXPECT_TRUE(GetErrors().empty());
2271 ASSERT_EQ(1u, loaded_.size());
[email protected]f484f8d52014-06-12 08:38:182272 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]91236521162012-05-24 15:02:512273}
2274#endif
2275
Karan Bhatiafe12281a2017-09-16 02:38:182276// Tests than an unpacked extension with an empty kMetadataFolder loads
2277// successfully.
2278TEST_F(ExtensionServiceTest, UnpackedExtensionWithEmptyMetadataFolder) {
Catherine Mullingsf5f1a1332017-08-04 18:29:192279 InitializeEmptyExtensionService();
Karan Bhatiafe12281a2017-09-16 02:38:182280 base::ScopedTempDir temp_dir;
2281 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2282 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
Devlin Cronineea1b7a2018-05-26 02:46:212283 base::FilePath metadata_dir = extension_dir.Append(kMetadataFolder);
Karan Bhatiafe12281a2017-09-16 02:38:182284 PersistExtensionWithPaths(extension_dir, {metadata_dir}, {});
2285 EXPECT_TRUE(base::DirectoryExists(metadata_dir));
2286
Devlin Cronineea1b7a2018-05-26 02:46:212287 UnpackedInstaller::Create(service())->Load(extension_dir);
Gabriel Charette01507a22017-09-27 21:30:082288 content::RunAllTasksUntilIdle();
Catherine Mullingsf5f1a1332017-08-04 18:29:192289 EXPECT_EQ(0u, GetErrors().size());
2290 EXPECT_EQ(1u, registry()->enabled_extensions().size());
Karan Bhatiafe12281a2017-09-16 02:38:182291
2292 // The kMetadataFolder should have been deleted since it did not contain
2293 // any non-reserved filenames.
2294 EXPECT_FALSE(base::DirectoryExists(metadata_dir));
Catherine Mullingsf5f1a1332017-08-04 18:29:192295}
2296
Karan Bhatiafe12281a2017-09-16 02:38:182297// Tests that an unpacked extension with only reserved filenames in the
2298// kMetadataFolder loads successfully.
2299TEST_F(ExtensionServiceTest, UnpackedExtensionWithReservedMetadataFiles) {
Karan Bhatia46178662017-09-11 21:50:452300 InitializeEmptyExtensionService();
Karan Bhatiafe12281a2017-09-16 02:38:182301 base::ScopedTempDir temp_dir;
2302 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2303 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
Devlin Cronineea1b7a2018-05-26 02:46:212304 base::FilePath metadata_dir = extension_dir.Append(kMetadataFolder);
Karan Bhatiafe12281a2017-09-16 02:38:182305 PersistExtensionWithPaths(
2306 extension_dir, {metadata_dir},
Devlin Cronineea1b7a2018-05-26 02:46:212307 file_util::GetReservedMetadataFilePaths(extension_dir));
Karan Bhatiafe12281a2017-09-16 02:38:182308 EXPECT_TRUE(base::DirectoryExists(metadata_dir));
2309
Devlin Cronineea1b7a2018-05-26 02:46:212310 UnpackedInstaller::Create(service())->Load(extension_dir);
Gabriel Charette01507a22017-09-27 21:30:082311 content::RunAllTasksUntilIdle();
Karan Bhatiafe12281a2017-09-16 02:38:182312 EXPECT_EQ(0u, GetErrors().size());
2313 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2314
2315 // The kMetadataFolder should have been deleted since it did not contain
2316 // any non-reserved filenames.
2317 EXPECT_FALSE(base::DirectoryExists(metadata_dir));
2318}
2319
2320// Tests that an unpacked extension with non-reserved files in the
2321// kMetadataFolder fails to load.
2322TEST_F(ExtensionServiceTest, UnpackedExtensionWithUserMetadataFiles) {
2323 InitializeEmptyExtensionService();
2324 base::ScopedTempDir temp_dir;
2325 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2326 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
Devlin Cronineea1b7a2018-05-26 02:46:212327 base::FilePath metadata_dir = extension_dir.Append(kMetadataFolder);
Karan Bhatiafe12281a2017-09-16 02:38:182328 base::FilePath non_reserved_file =
2329 metadata_dir.Append(FILE_PATH_LITERAL("a.txt"));
2330 PersistExtensionWithPaths(
2331 extension_dir, {metadata_dir},
Devlin Cronineea1b7a2018-05-26 02:46:212332 {file_util::GetVerifiedContentsPath(extension_dir), non_reserved_file});
Karan Bhatiafe12281a2017-09-16 02:38:182333 EXPECT_TRUE(base::PathExists(non_reserved_file));
2334
Devlin Cronineea1b7a2018-05-26 02:46:212335 UnpackedInstaller::Create(service())->Load(extension_dir);
Gabriel Charette01507a22017-09-27 21:30:082336 content::RunAllTasksUntilIdle();
Karan Bhatiafe12281a2017-09-16 02:38:182337 ASSERT_EQ(1u, GetErrors().size());
2338
2339 // Format expected error string.
2340 std::string expected("Failed to load extension from: ");
2341 expected.append(extension_dir.MaybeAsASCII())
2342 .append(
2343 ". Cannot load extension with file or directory name _metadata. "
2344 "Filenames starting with \"_\" are reserved for use by the system.");
2345
2346 EXPECT_EQ(base::UTF8ToUTF16(expected), GetErrors()[0]);
2347 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2348
2349 // Non-reserved filepaths inside the kMetadataFolder should not have been
2350 // deleted.
2351 EXPECT_TRUE(base::PathExists(non_reserved_file));
2352}
2353
2354// Tests than an unpacked extension with an empty kMetadataFolder and a folder
2355// beginning with "_" fails to load.
2356TEST_F(ExtensionServiceTest,
2357 UnpackedExtensionWithEmptyMetadataAndUnderscoreFolders) {
2358 InitializeEmptyExtensionService();
2359 base::ScopedTempDir temp_dir;
2360 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2361 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
Devlin Cronineea1b7a2018-05-26 02:46:212362 base::FilePath metadata_dir = extension_dir.Append(kMetadataFolder);
Karan Bhatiafe12281a2017-09-16 02:38:182363 PersistExtensionWithPaths(
2364 extension_dir,
2365 {metadata_dir, extension_dir.Append(FILE_PATH_LITERAL("_badfolder"))},
2366 {});
2367
Devlin Cronineea1b7a2018-05-26 02:46:212368 UnpackedInstaller::Create(service())->Load(extension_dir);
Gabriel Charette01507a22017-09-27 21:30:082369 content::RunAllTasksUntilIdle();
Catherine Mullingsf5f1a1332017-08-04 18:29:192370 EXPECT_EQ(1u, GetErrors().size());
2371
2372 // Format expected error string.
2373 std::string expected("Failed to load extension from: ");
Karan Bhatiafe12281a2017-09-16 02:38:182374 expected.append(extension_dir.MaybeAsASCII())
Catherine Mullingsf5f1a1332017-08-04 18:29:192375 .append(
Karan Bhatiafe12281a2017-09-16 02:38:182376 ". Cannot load extension with file or directory name _badfolder. "
2377 "Filenames starting with \"_\" are reserved for use by the system.");
Catherine Mullingsf5f1a1332017-08-04 18:29:192378
Karan Bhatiafe12281a2017-09-16 02:38:182379 EXPECT_EQ(base::UTF8ToUTF16(expected), GetErrors()[0]);
Catherine Mullingsf5f1a1332017-08-04 18:29:192380 EXPECT_EQ(0u, registry()->enabled_extensions().size());
Karan Bhatiafe12281a2017-09-16 02:38:182381
2382 // The kMetadataFolder should have been deleted since it did not contain any
2383 // non-reserved filenames.
2384 EXPECT_FALSE(base::DirectoryExists(metadata_dir));
Catherine Mullingsf5f1a1332017-08-04 18:29:192385}
2386
Karan Bhatiafe12281a2017-09-16 02:38:182387// Tests that an unpacked extension with an arbitrary folder beginning with an
2388// underscore can't load.
[email protected]5ccca8ad2013-08-19 22:35:342389TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2390 InitializeEmptyExtensionService();
Karan Bhatiafe12281a2017-09-16 02:38:182391 base::ScopedTempDir temp_dir;
2392 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2393 base::FilePath extension_dir = base::MakeAbsoluteFilePath(temp_dir.GetPath());
2394 base::FilePath underscore_folder =
2395 extension_dir.Append(FILE_PATH_LITERAL("_badfolder"));
2396 PersistExtensionWithPaths(
2397 extension_dir, {underscore_folder},
2398 {underscore_folder.Append(FILE_PATH_LITERAL("a.js"))});
2399 EXPECT_TRUE(base::DirectoryExists(underscore_folder));
2400
Devlin Cronineea1b7a2018-05-26 02:46:212401 UnpackedInstaller::Create(service())->Load(extension_dir);
Gabriel Charette01507a22017-09-27 21:30:082402 content::RunAllTasksUntilIdle();
[email protected]5ccca8ad2013-08-19 22:35:342403 EXPECT_EQ(1u, GetErrors().size());
Catherine Mullingsf5f1a1332017-08-04 18:29:192404
2405 // Format expected error string.
2406 std::string expected("Failed to load extension from: ");
Karan Bhatiafe12281a2017-09-16 02:38:182407 expected.append(extension_dir.MaybeAsASCII())
Catherine Mullingsf5f1a1332017-08-04 18:29:192408 .append(
Karan Bhatiafe12281a2017-09-16 02:38:182409 ". Cannot load extension with file or directory name _badfolder. "
2410 "Filenames starting with \"_\" are reserved for use by the system.");
Catherine Mullingsf5f1a1332017-08-04 18:29:192411
Karan Bhatiafe12281a2017-09-16 02:38:182412 EXPECT_EQ(base::UTF8ToUTF16(expected), GetErrors()[0]);
[email protected]f484f8d52014-06-12 08:38:182413 EXPECT_EQ(0u, registry()->enabled_extensions().size());
[email protected]5ccca8ad2013-08-19 22:35:342414}
2415
[email protected]d9a61e12012-11-14 02:43:472416TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
[email protected]eaa7dd182010-12-14 11:09:002417 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182418 service()->Init();
[email protected]b1ac70462013-08-14 21:33:302419
[email protected]f484f8d52014-06-12 08:38:182420 base::FilePath theme_path = data_dir().AppendASCII("theme_i18n");
[email protected]584245e52010-06-17 01:08:132421
[email protected]8f512c72011-11-22 21:02:502422 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
[email protected]584245e52010-06-17 01:08:132423
[email protected]584245e52010-06-17 01:08:132424 EXPECT_EQ(0u, GetErrors().size());
[email protected]f484f8d52014-06-12 08:38:182425 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]8f512c72011-11-22 21:02:502426 EXPECT_EQ("name", theme->name());
2427 EXPECT_EQ("description", theme->description());
[email protected]584245e52010-06-17 01:08:132428}
2429
[email protected]d9a61e12012-11-14 02:43:472430TEST_F(ExtensionServiceTest, InstallApps) {
[email protected]eaa7dd182010-12-14 11:09:002431 InitializeEmptyExtensionService();
[email protected]6d2e60bd2010-06-03 22:37:392432
2433 // An empty app.
[email protected]f484f8d52014-06-12 08:38:182434 const Extension* app =
2435 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
[email protected]6d2e60bd2010-06-03 22:37:392436 int pref_count = 0;
2437 ValidatePrefKeyCount(++pref_count);
[email protected]f484f8d52014-06-12 08:38:182438 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]8f512c72011-11-22 21:02:502439 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:402440 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
[email protected]6d2e60bd2010-06-03 22:37:392441
2442 // Another app with non-overlapping extent. Should succeed.
[email protected]f484f8d52014-06-12 08:38:182443 PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
[email protected]6d2e60bd2010-06-03 22:37:392444 ValidatePrefKeyCount(++pref_count);
2445
2446 // A third app whose extent overlaps the first. Should fail.
[email protected]f484f8d52014-06-12 08:38:182447 PackAndInstallCRX(data_dir().AppendASCII("app3"), INSTALL_FAILED);
[email protected]cd10e282010-10-26 21:04:512448 ValidatePrefKeyCount(pref_count);
[email protected]6d2e60bd2010-06-03 22:37:392449}
2450
[email protected]b6e64fd2011-08-09 19:49:192451// Tests that file access is OFF by default.
[email protected]d9a61e12012-11-14 02:43:472452TEST_F(ExtensionServiceTest, DefaultFileAccess) {
[email protected]b6e64fd2011-08-09 19:49:192453 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182454 const Extension* extension = PackAndInstallCRX(
2455 data_dir().AppendASCII("permissions").AppendASCII("files"), INSTALL_NEW);
[email protected]b6e64fd2011-08-09 19:49:192456 EXPECT_EQ(0u, GetErrors().size());
[email protected]f484f8d52014-06-12 08:38:182457 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]7c82539c2014-02-19 06:09:172458 EXPECT_FALSE(
[email protected]f484f8d52014-06-12 08:38:182459 ExtensionPrefs::Get(profile())->AllowFileAccess(extension->id()));
[email protected]b6e64fd2011-08-09 19:49:192460}
2461
[email protected]d9a61e12012-11-14 02:43:472462TEST_F(ExtensionServiceTest, UpdateApps) {
[email protected]15300d92011-01-19 18:44:302463 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182464 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
[email protected]15300d92011-01-19 18:44:302465
2466 // First install v1 of a hosted app.
[email protected]8f512c72011-11-22 21:02:502467 const Extension* extension =
2468 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
[email protected]f484f8d52014-06-12 08:38:182469 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]8f512c72011-11-22 21:02:502470 std::string id = extension->id();
Devlin Cronin03bf2d22017-12-20 08:21:052471 ASSERT_EQ(std::string("1"), extension->version().GetString());
[email protected]15300d92011-01-19 18:44:302472
2473 // Now try updating to v2.
2474 UpdateExtension(id,
2475 extensions_path.AppendASCII("v2.crx"),
2476 ENABLED);
2477 ASSERT_EQ(std::string("2"),
David Bertoni58c113a2019-08-02 19:53:262478 registry()
2479 ->GetExtensionById(id, ExtensionRegistry::ENABLED)
2480 ->version()
2481 .GetString());
[email protected]15300d92011-01-19 18:44:302482}
2483
[email protected]e6a6c2e02012-01-13 00:06:482484// Verifies that the NTP page and launch ordinals are kept when updating apps.
[email protected]d9a61e12012-11-14 02:43:472485TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
[email protected]e6a6c2e02012-01-13 00:06:482486 InitializeEmptyExtensionService();
deepak.m14ba69e62015-11-17 05:42:122487 AppSorting* sorting = ExtensionSystem::Get(profile())->app_sorting();
[email protected]f484f8d52014-06-12 08:38:182488 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
[email protected]e6a6c2e02012-01-13 00:06:482489
2490 // First install v1 of a hosted app.
2491 const Extension* extension =
2492 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
[email protected]f484f8d52014-06-12 08:38:182493 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]e6a6c2e02012-01-13 00:06:482494 std::string id = extension->id();
Devlin Cronin03bf2d22017-12-20 08:21:052495 ASSERT_EQ(std::string("1"), extension->version().GetString());
[email protected]e6a6c2e02012-01-13 00:06:482496
2497 // Modify the ordinals so we can distinguish them from the defaults.
[email protected]36b643212012-09-07 12:53:002498 syncer::StringOrdinal new_page_ordinal =
2499 sorting->GetPageOrdinal(id).CreateAfter();
2500 syncer::StringOrdinal new_launch_ordinal =
[email protected]e6a6c2e02012-01-13 00:06:482501 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2502
2503 sorting->SetPageOrdinal(id, new_page_ordinal);
2504 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2505
2506 // Now try updating to v2.
2507 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2508 ASSERT_EQ(std::string("2"),
David Bertoni58c113a2019-08-02 19:53:262509 registry()
2510 ->GetExtensionById(id, ExtensionRegistry::ENABLED)
2511 ->version()
2512 .GetString());
[email protected]e6a6c2e02012-01-13 00:06:482513
2514 // Verify that the ordinals match.
[email protected]36b643212012-09-07 12:53:002515 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2516 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
[email protected]e6a6c2e02012-01-13 00:06:482517}
2518
[email protected]b873cd92012-02-09 21:51:482519// Ensures that the CWS has properly initialized ordinals.
[email protected]d9a61e12012-11-14 02:43:472520TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
[email protected]b873cd92012-02-09 21:51:482521 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182522 service()->component_loader()->Add(
[email protected]650b2d52013-02-10 03:41:452523 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
[email protected]f484f8d52014-06-12 08:38:182524 service()->Init();
[email protected]b873cd92012-02-09 21:51:482525
deepak.m14ba69e62015-11-17 05:42:122526 AppSorting* sorting = ExtensionSystem::Get(profile())->app_sorting();
Devlin Cronineea1b7a2018-05-26 02:46:212527 EXPECT_TRUE(sorting->GetPageOrdinal(kWebStoreAppId).IsValid());
2528 EXPECT_TRUE(sorting->GetAppLaunchOrdinal(kWebStoreAppId).IsValid());
[email protected]b873cd92012-02-09 21:51:482529}
2530
[email protected]fe10c202013-03-11 23:44:342531TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
[email protected]eaa7dd182010-12-14 11:09:002532 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182533 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
[email protected]c2c263c2010-08-13 21:59:482534
[email protected]c2c263c2010-08-13 21:59:482535 int pref_count = 0;
[email protected]c2c263c2010-08-13 21:59:482536
2537 // Install app1 with unlimited storage.
[email protected]8f512c72011-11-22 21:02:502538 const Extension* extension =
[email protected]f484f8d52014-06-12 08:38:182539 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
[email protected]c2c263c2010-08-13 21:59:482540 ValidatePrefKeyCount(++pref_count);
[email protected]f484f8d52014-06-12 08:38:182541 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]c2c263c2010-08-13 21:59:482542 const std::string id1 = extension->id();
[email protected]076ebeda2014-06-06 21:47:262543 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:062544 APIPermission::kUnlimitedStorage));
[email protected]cced75a2011-05-20 08:31:122545 EXPECT_TRUE(extension->web_extent().MatchesURL(
Devlin Cronineea1b7a2018-05-26 02:46:212546 AppLaunchInfo::GetFullLaunchURL(extension)));
2547 const GURL origin1(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
[email protected]f484f8d52014-06-12 08:38:182548 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2549 origin1));
[email protected]c2c263c2010-08-13 21:59:482550
2551 // Install app2 from the same origin with unlimited storage.
[email protected]f484f8d52014-06-12 08:38:182552 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
[email protected]c2c263c2010-08-13 21:59:482553 ValidatePrefKeyCount(++pref_count);
[email protected]f484f8d52014-06-12 08:38:182554 ASSERT_EQ(2u, registry()->enabled_extensions().size());
[email protected]c2c263c2010-08-13 21:59:482555 const std::string id2 = extension->id();
[email protected]076ebeda2014-06-06 21:47:262556 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:062557 APIPermission::kUnlimitedStorage));
[email protected]cced75a2011-05-20 08:31:122558 EXPECT_TRUE(extension->web_extent().MatchesURL(
Devlin Cronineea1b7a2018-05-26 02:46:212559 AppLaunchInfo::GetFullLaunchURL(extension)));
2560 const GURL origin2(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
[email protected]c2c263c2010-08-13 21:59:482561 EXPECT_EQ(origin1, origin2);
[email protected]f484f8d52014-06-12 08:38:182562 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2563 origin2));
[email protected]19eb80152011-02-26 00:28:432564
[email protected]c2c263c2010-08-13 21:59:482565 // Uninstall one of them, unlimited storage should still be granted
2566 // to the origin.
Devlin Cronin6fd1cd62017-12-05 19:13:572567 UninstallExtension(id1);
[email protected]f484f8d52014-06-12 08:38:182568 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2569 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2570 origin1));
[email protected]19eb80152011-02-26 00:28:432571
[email protected]c2c263c2010-08-13 21:59:482572 // Uninstall the other, unlimited storage should be revoked.
Devlin Cronin6fd1cd62017-12-05 19:13:572573 UninstallExtension(id2);
[email protected]f484f8d52014-06-12 08:38:182574 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2575 EXPECT_FALSE(
2576 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2577 origin2));
[email protected]c2c263c2010-08-13 21:59:482578}
2579
[email protected]d9a61e12012-11-14 02:43:472580TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
[email protected]eaa7dd182010-12-14 11:09:002581 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182582 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
[email protected]654512b2010-09-01 02:09:422583
[email protected]654512b2010-09-01 02:09:422584 int pref_count = 0;
2585
[email protected]8f512c72011-11-22 21:02:502586 const Extension* extension =
[email protected]f484f8d52014-06-12 08:38:182587 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
[email protected]654512b2010-09-01 02:09:422588 ValidatePrefKeyCount(++pref_count);
[email protected]f484f8d52014-06-12 08:38:182589 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]654512b2010-09-01 02:09:422590 EXPECT_TRUE(extension->is_app());
2591 const std::string id1 = extension->id();
Devlin Cronineea1b7a2018-05-26 02:46:212592 const GURL origin1(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
[email protected]f484f8d52014-06-12 08:38:182593 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2594 origin1));
[email protected]654512b2010-09-01 02:09:422595
2596 // App 4 has a different origin (maps.google.com).
[email protected]f484f8d52014-06-12 08:38:182597 extension = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
[email protected]654512b2010-09-01 02:09:422598 ValidatePrefKeyCount(++pref_count);
[email protected]f484f8d52014-06-12 08:38:182599 ASSERT_EQ(2u, registry()->enabled_extensions().size());
[email protected]654512b2010-09-01 02:09:422600 const std::string id2 = extension->id();
Devlin Cronineea1b7a2018-05-26 02:46:212601 const GURL origin2(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
[email protected]654512b2010-09-01 02:09:422602 ASSERT_NE(origin1, origin2);
[email protected]f484f8d52014-06-12 08:38:182603 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2604 origin2));
[email protected]654512b2010-09-01 02:09:422605
Devlin Cronin6fd1cd62017-12-05 19:13:572606 UninstallExtension(id1);
[email protected]f484f8d52014-06-12 08:38:182607 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]654512b2010-09-01 02:09:422608
Devlin Cronin6fd1cd62017-12-05 19:13:572609 UninstallExtension(id2);
[email protected]654512b2010-09-01 02:09:422610
[email protected]f484f8d52014-06-12 08:38:182611 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2612 EXPECT_FALSE(
2613 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2614 origin1));
2615 EXPECT_FALSE(
2616 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2617 origin2));
[email protected]654512b2010-09-01 02:09:422618}
2619
[email protected]894bb502009-05-21 22:39:572620// Test that when an extension version is reinstalled, nothing happens.
[email protected]d9a61e12012-11-14 02:43:472621TEST_F(ExtensionServiceTest, Reinstall) {
[email protected]eaa7dd182010-12-14 11:09:002622 InitializeEmptyExtensionService();
[email protected]894bb502009-05-21 22:39:572623
2624 // A simple extension that should install without error.
[email protected]f484f8d52014-06-12 08:38:182625 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502626 InstallCRX(path, INSTALL_NEW);
[email protected]894bb502009-05-21 22:39:572627
[email protected]25b34332009-06-05 21:53:192628 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342629 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:402630 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
[email protected]894bb502009-05-21 22:39:572631
[email protected]ca3dbf52010-05-19 22:27:062632 // Reinstall the same version, it should overwrite the previous one.
[email protected]8f512c72011-11-22 21:02:502633 InstallCRX(path, INSTALL_UPDATED);
[email protected]894bb502009-05-21 22:39:572634
[email protected]25b34332009-06-05 21:53:192635 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342636 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:402637 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
[email protected]894bb502009-05-21 22:39:572638}
2639
[email protected]620db1762011-07-15 21:57:342640// Test that we can determine if extensions came from the
2641// Chrome web store.
[email protected]d9a61e12012-11-14 02:43:472642TEST_F(ExtensionServiceTest, FromWebStore) {
[email protected]8266d662011-07-12 21:53:262643 InitializeEmptyExtensionService();
2644
2645 // A simple extension that should install without error.
[email protected]f484f8d52014-06-12 08:38:182646 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502647 // Not from web store.
2648 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2649 std::string id = extension->id();
[email protected]8266d662011-07-12 21:53:262650
[email protected]8266d662011-07-12 21:53:262651 ValidatePrefKeyCount(1);
[email protected]3f2a2fa2013-09-24 02:55:252652 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
[email protected]620db1762011-07-15 21:57:342653 ASSERT_FALSE(extension->from_webstore());
[email protected]8266d662011-07-12 21:53:262654
[email protected]8266d662011-07-12 21:53:262655 // Test install from web store.
[email protected]8f512c72011-11-22 21:02:502656 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
[email protected]8266d662011-07-12 21:53:262657
[email protected]8266d662011-07-12 21:53:262658 ValidatePrefKeyCount(1);
[email protected]3f2a2fa2013-09-24 02:55:252659 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
[email protected]620db1762011-07-15 21:57:342660
2661 // Reload so extension gets reinitialized with new value.
[email protected]f484f8d52014-06-12 08:38:182662 service()->ReloadExtensionsForTest();
David Bertoni58c113a2019-08-02 19:53:262663 extension = registry()->GetExtensionById(id, ExtensionRegistry::ENABLED);
[email protected]620db1762011-07-15 21:57:342664 ASSERT_TRUE(extension->from_webstore());
[email protected]3d729722011-09-20 02:57:092665
2666 // Upgrade to version 2.0
[email protected]f484f8d52014-06-12 08:38:182667 path = data_dir().AppendASCII("good2.crx");
[email protected]3d729722011-09-20 02:57:092668 UpdateExtension(good_crx, path, ENABLED);
2669 ValidatePrefKeyCount(1);
[email protected]3f2a2fa2013-09-24 02:55:252670 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
[email protected]8266d662011-07-12 21:53:262671}
2672
[email protected]fbcc40302009-06-12 20:45:452673// Test upgrading a signed extension.
[email protected]d9a61e12012-11-14 02:43:472674TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
[email protected]eaa7dd182010-12-14 11:09:002675 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:452676
[email protected]f484f8d52014-06-12 08:38:182677 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502678 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2679 std::string id = extension->id();
[email protected]fbcc40302009-06-12 20:45:452680
Devlin Cronin03bf2d22017-12-20 08:21:052681 ASSERT_EQ("1.0.0.0", extension->version().GetString());
[email protected]fbcc40302009-06-12 20:45:452682 ASSERT_EQ(0u, GetErrors().size());
2683
[email protected]e7554c3f2013-05-29 00:36:562684 // Upgrade to version 1.0.0.1.
2685 // Also test that the extension's old and new title are correctly retrieved.
[email protected]f484f8d52014-06-12 08:38:182686 path = data_dir().AppendASCII("good2.crx");
[email protected]e7554c3f2013-05-29 00:36:562687 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
David Bertoni58c113a2019-08-02 19:53:262688 extension = registry()->GetExtensionById(id, ExtensionRegistry::ENABLED);
[email protected]fbcc40302009-06-12 20:45:452689
Devlin Cronin03bf2d22017-12-20 08:21:052690 ASSERT_EQ("1.0.0.1", extension->version().GetString());
[email protected]e7554c3f2013-05-29 00:36:562691 ASSERT_EQ("My updated extension 1", extension->name());
[email protected]fbcc40302009-06-12 20:45:452692 ASSERT_EQ(0u, GetErrors().size());
2693}
2694
2695// Test upgrading a signed extension with a bad signature.
[email protected]d9a61e12012-11-14 02:43:472696TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
[email protected]eaa7dd182010-12-14 11:09:002697 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:452698
[email protected]f484f8d52014-06-12 08:38:182699 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502700 InstallCRX(path, INSTALL_NEW);
[email protected]fbcc40302009-06-12 20:45:452701
2702 // Try upgrading with a bad signature. This should fail during the unpack,
2703 // because the key will not match the signature.
[email protected]f484f8d52014-06-12 08:38:182704 path = data_dir().AppendASCII("bad_signature.crx");
[email protected]8f512c72011-11-22 21:02:502705 InstallCRX(path, INSTALL_FAILED);
[email protected]fbcc40302009-06-12 20:45:452706}
2707
[email protected]e957fe52009-06-23 16:51:052708// Test a normal update via the UpdateExtension API
[email protected]d9a61e12012-11-14 02:43:472709TEST_F(ExtensionServiceTest, UpdateExtension) {
[email protected]eaa7dd182010-12-14 11:09:002710 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052711
[email protected]f484f8d52014-06-12 08:38:182712 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]e957fe52009-06-23 16:51:052713
[email protected]8f512c72011-11-22 21:02:502714 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]e957fe52009-06-23 16:51:052715 ASSERT_EQ("1.0.0.0", good->VersionString());
2716 ASSERT_EQ(good_crx, good->id());
2717
[email protected]f484f8d52014-06-12 08:38:182718 path = data_dir().AppendASCII("good2.crx");
[email protected]4416c5a2010-06-26 01:28:572719 UpdateExtension(good_crx, path, ENABLED);
David Bertoni58c113a2019-08-02 19:53:262720 ASSERT_EQ("1.0.0.1",
2721 registry()
2722 ->GetExtensionById(good_crx, ExtensionRegistry::ENABLED)
2723 ->version()
2724 .GetString());
[email protected]e957fe52009-06-23 16:51:052725}
2726
[email protected]3c4abc82012-10-22 22:25:542727// Extensions should not be updated during browser shutdown.
[email protected]d9a61e12012-11-14 02:43:472728TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
[email protected]3c4abc82012-10-22 22:25:542729 InitializeEmptyExtensionService();
2730
2731 // Install an extension.
[email protected]f484f8d52014-06-12 08:38:182732 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]3c4abc82012-10-22 22:25:542733 const Extension* good = InstallCRX(path, INSTALL_NEW);
2734 ASSERT_EQ(good_crx, good->id());
2735
2736 // Simulate shutdown.
[email protected]f484f8d52014-06-12 08:38:182737 service()->set_browser_terminating_for_test(true);
[email protected]3c4abc82012-10-22 22:25:542738
2739 // Update should fail and extension should not be updated.
[email protected]f484f8d52014-06-12 08:38:182740 path = data_dir().AppendASCII("good2.crx");
Joshua Pawlickifd01b7c2019-01-17 16:18:342741 bool updated = service()->UpdateExtension(
2742 CRXFileInfo(good_crx, GetTestVerifierFormat(), path), true, NULL);
[email protected]3c4abc82012-10-22 22:25:542743 ASSERT_FALSE(updated);
David Bertoni58c113a2019-08-02 19:53:262744 ASSERT_EQ("1.0.0.0",
2745 registry()
2746 ->GetExtensionById(good_crx, ExtensionRegistry::ENABLED)
2747 ->version()
2748 .GetString());
[email protected]3c4abc82012-10-22 22:25:542749}
2750
[email protected]e957fe52009-06-23 16:51:052751// Test updating a not-already-installed extension - this should fail
[email protected]d9a61e12012-11-14 02:43:472752TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
[email protected]eaa7dd182010-12-14 11:09:002753 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052754
[email protected]f484f8d52014-06-12 08:38:182755 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572756 UpdateExtension(good_crx, path, UPDATED);
Gabriel Charette01507a22017-09-27 21:30:082757 content::RunAllTasksUntilIdle();
[email protected]e957fe52009-06-23 16:51:052758
[email protected]f484f8d52014-06-12 08:38:182759 ASSERT_EQ(0u, registry()->enabled_extensions().size());
[email protected]e957fe52009-06-23 16:51:052760 ASSERT_FALSE(installed_);
2761 ASSERT_EQ(0u, loaded_.size());
2762}
2763
2764// Makes sure you can't downgrade an extension via UpdateExtension
[email protected]d9a61e12012-11-14 02:43:472765TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
[email protected]eaa7dd182010-12-14 11:09:002766 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052767
[email protected]f484f8d52014-06-12 08:38:182768 base::FilePath path = data_dir().AppendASCII("good2.crx");
[email protected]e957fe52009-06-23 16:51:052769
[email protected]8f512c72011-11-22 21:02:502770 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]e957fe52009-06-23 16:51:052771 ASSERT_EQ("1.0.0.1", good->VersionString());
2772 ASSERT_EQ(good_crx, good->id());
2773
2774 // Change path from good2.crx -> good.crx
[email protected]f484f8d52014-06-12 08:38:182775 path = data_dir().AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572776 UpdateExtension(good_crx, path, FAILED);
David Bertoni58c113a2019-08-02 19:53:262777 ASSERT_EQ("1.0.0.1",
2778 registry()
2779 ->GetExtensionById(good_crx, ExtensionRegistry::ENABLED)
2780 ->version()
2781 .GetString());
[email protected]e957fe52009-06-23 16:51:052782}
2783
2784// Make sure calling update with an identical version does nothing
[email protected]d9a61e12012-11-14 02:43:472785TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
[email protected]eaa7dd182010-12-14 11:09:002786 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052787
[email protected]f484f8d52014-06-12 08:38:182788 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]e957fe52009-06-23 16:51:052789
[email protected]8f512c72011-11-22 21:02:502790 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]e957fe52009-06-23 16:51:052791 ASSERT_EQ(good_crx, good->id());
[email protected]4416c5a2010-06-26 01:28:572792 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]aa142702010-03-26 01:26:332793}
2794
[email protected]dbec3792010-08-10 00:08:452795// Tests that updating an extension does not clobber old state.
[email protected]d9a61e12012-11-14 02:43:472796TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
[email protected]eaa7dd182010-12-14 11:09:002797 InitializeEmptyExtensionService();
[email protected]dbec3792010-08-10 00:08:452798
[email protected]f484f8d52014-06-12 08:38:182799 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]dbec3792010-08-10 00:08:452800
[email protected]8f512c72011-11-22 21:02:502801 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]dbec3792010-08-10 00:08:452802 ASSERT_EQ("1.0.0.0", good->VersionString());
2803 ASSERT_EQ(good_crx, good->id());
2804
2805 // Disable it and allow it to run in incognito. These settings should carry
2806 // over to the updated version.
Devlin Cronineea1b7a2018-05-26 02:46:212807 service()->DisableExtension(good->id(), disable_reason::DISABLE_USER_ACTION);
2808 util::SetIsIncognitoEnabled(good->id(), profile(), true);
[email protected]dbec3792010-08-10 00:08:452809
[email protected]f484f8d52014-06-12 08:38:182810 path = data_dir().AppendASCII("good2.crx");
[email protected]dbec3792010-08-10 00:08:452811 UpdateExtension(good_crx, path, INSTALLED);
[email protected]f484f8d52014-06-12 08:38:182812 ASSERT_EQ(1u, registry()->disabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:262813 const Extension* good2 =
2814 registry()->GetExtensionById(good_crx, ExtensionRegistry::COMPATIBILITY);
Devlin Cronin03bf2d22017-12-20 08:21:052815 ASSERT_EQ("1.0.0.1", good2->version().GetString());
Devlin Cronineea1b7a2018-05-26 02:46:212816 EXPECT_TRUE(util::IsIncognitoEnabled(good2->id(), profile()));
2817 EXPECT_EQ(disable_reason::DISABLE_USER_ACTION,
treibaac30ec2015-06-10 09:18:092818 ExtensionPrefs::Get(profile())->GetDisableReasons(good2->id()));
[email protected]dbec3792010-08-10 00:08:452819}
2820
[email protected]5eb375e92010-11-26 07:50:412821// Tests that updating preserves extension location.
[email protected]d9a61e12012-11-14 02:43:472822TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
[email protected]eaa7dd182010-12-14 11:09:002823 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:182824 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]5eb375e92010-11-26 07:50:412825
catmullings22bc2372016-11-02 19:59:352826 const Extension* good = InstallCRX(path, Manifest::EXTERNAL_PREF, INSTALL_NEW,
2827 Extension::NO_FLAGS);
[email protected]5eb375e92010-11-26 07:50:412828
2829 ASSERT_EQ("1.0.0.0", good->VersionString());
2830 ASSERT_EQ(good_crx, good->id());
2831
[email protected]f484f8d52014-06-12 08:38:182832 path = data_dir().AppendASCII("good2.crx");
[email protected]5eb375e92010-11-26 07:50:412833 UpdateExtension(good_crx, path, ENABLED);
David Bertoni58c113a2019-08-02 19:53:262834 const Extension* good2 =
2835 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED);
Devlin Cronin03bf2d22017-12-20 08:21:052836 ASSERT_EQ("1.0.0.1", good2->version().GetString());
[email protected]1d5e58b2013-01-31 08:41:402837 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
[email protected]5eb375e92010-11-26 07:50:412838}
2839
[email protected]66e26872010-12-03 20:07:252840// Makes sure that LOAD extension types can downgrade.
[email protected]d9a61e12012-11-14 02:43:472841TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
[email protected]eaa7dd182010-12-14 11:09:002842 InitializeEmptyExtensionService();
[email protected]66e26872010-12-03 20:07:252843
[email protected]ea1a3f62012-11-16 20:34:232844 base::ScopedTempDir temp;
[email protected]66e26872010-12-03 20:07:252845 ASSERT_TRUE(temp.CreateUniqueTempDir());
2846
2847 // We'll write the extension manifest dynamically to a temporary path
2848 // to make it easier to change the version number.
vabr9142fe22016-09-08 13:19:222849 base::FilePath extension_path = temp.GetPath();
Devlin Cronineea1b7a2018-05-26 02:46:212850 base::FilePath manifest_path = extension_path.Append(kManifestFilename);
[email protected]7567484142013-07-11 17:36:072851 ASSERT_FALSE(base::PathExists(manifest_path));
[email protected]66e26872010-12-03 20:07:252852
2853 // Start with version 2.0.
[email protected]023b3d12013-12-23 18:46:492854 base::DictionaryValue manifest;
[email protected]66e26872010-12-03 20:07:252855 manifest.SetString("version", "2.0");
2856 manifest.SetString("name", "LOAD Downgrade Test");
[email protected]b3d52852011-12-07 01:01:112857 manifest.SetInteger("manifest_version", 2);
[email protected]66e26872010-12-03 20:07:252858
2859 JSONFileValueSerializer serializer(manifest_path);
2860 ASSERT_TRUE(serializer.Serialize(manifest));
2861
Devlin Cronineea1b7a2018-05-26 02:46:212862 UnpackedInstaller::Create(service())->Load(extension_path);
Gabriel Charette01507a22017-09-27 21:30:082863 content::RunAllTasksUntilIdle();
[email protected]66e26872010-12-03 20:07:252864
2865 EXPECT_EQ(0u, GetErrors().size());
2866 ASSERT_EQ(1u, loaded_.size());
[email protected]12075d12013-02-27 05:38:052867 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
[email protected]f484f8d52014-06-12 08:38:182868 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]66e26872010-12-03 20:07:252869 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2870
2871 // Now set the version number to 1.0, reload the extensions and verify that
2872 // the downgrade was accepted.
2873 manifest.SetString("version", "1.0");
2874 ASSERT_TRUE(serializer.Serialize(manifest));
2875
Devlin Cronineea1b7a2018-05-26 02:46:212876 UnpackedInstaller::Create(service())->Load(extension_path);
Gabriel Charette01507a22017-09-27 21:30:082877 content::RunAllTasksUntilIdle();
[email protected]66e26872010-12-03 20:07:252878
2879 EXPECT_EQ(0u, GetErrors().size());
2880 ASSERT_EQ(1u, loaded_.size());
[email protected]12075d12013-02-27 05:38:052881 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
[email protected]f484f8d52014-06-12 08:38:182882 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]66e26872010-12-03 20:07:252883 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2884}
2885
[email protected]7fa19f82010-12-21 19:40:082886namespace {
2887
[email protected]8f3bcbd2013-06-05 08:42:402888bool IsExtension(const Extension* extension) {
2889 return extension->GetType() == Manifest::TYPE_EXTENSION;
[email protected]7fa19f82010-12-21 19:40:082890}
2891
[email protected]757d60a2014-05-23 00:11:442892#if defined(ENABLE_BLACKLIST_TESTS)
2893std::set<std::string> StringSet(const std::string& s) {
2894 std::set<std::string> set;
2895 set.insert(s);
2896 return set;
2897}
2898std::set<std::string> StringSet(const std::string& s1, const std::string& s2) {
2899 std::set<std::string> set = StringSet(s1);
2900 set.insert(s2);
2901 return set;
2902}
2903#endif // defined(ENABLE_BLACKLIST_TESTS)
2904
[email protected]7fa19f82010-12-21 19:40:082905} // namespace
2906
[email protected]aa142702010-03-26 01:26:332907// Test adding a pending extension.
[email protected]d9a61e12012-11-14 02:43:472908TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
[email protected]eaa7dd182010-12-14 11:09:002909 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332910
[email protected]145a317b2011-04-12 16:03:462911 const std::string kFakeId(all_zero);
[email protected]aa142702010-03-26 01:26:332912 const GURL kFakeUpdateURL("http:://fake.update/url");
[email protected]21db9ef2014-05-16 02:06:272913 const bool kFakeRemoteInstall(false);
[email protected]aa142702010-03-26 01:26:332914
[email protected]21db9ef2014-05-16 02:06:272915 EXPECT_TRUE(
[email protected]6338fa32014-07-16 21:41:592916 service()->pending_extension_manager()->AddFromSync(
2917 kFakeId,
2918 kFakeUpdateURL,
treibe960e282015-09-11 10:38:082919 base::Version(),
[email protected]6338fa32014-07-16 21:41:592920 &IsExtension,
mamir192d7882016-06-22 17:10:162921 kFakeRemoteInstall));
[email protected]b2907fd2011-03-25 16:43:372922
Devlin Cronineea1b7a2018-05-26 02:46:212923 const PendingExtensionInfo* pending_extension_info;
[email protected]f484f8d52014-06-12 08:38:182924 ASSERT_TRUE((pending_extension_info =
2925 service()->pending_extension_manager()->GetById(kFakeId)));
[email protected]51a3bf8b2012-06-08 22:53:062926 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
2927 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
[email protected]24b5fd42014-05-17 01:14:182928 // Use
2929 // EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install())
2930 // instead of
2931 // EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install())
2932 // as gcc 4.7 issues the following warning on EXPECT_EQ(false, x), which is
2933 // turned into an error with -Werror=conversion-null:
2934 // converting 'false' to pointer type for argument 1 of
2935 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)'
2936 // https://code.google.com/p/googletest/issues/detail?id=458
2937 EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install());
[email protected]aa142702010-03-26 01:26:332938}
2939
[email protected]aa142702010-03-26 01:26:332940namespace {
2941const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2942const char kGoodUpdateURL[] = "http://good.update/url";
treibe960e282015-09-11 10:38:082943const char kGoodVersion[] = "1";
[email protected]8ef78fd2010-08-19 17:14:322944const bool kGoodIsFromSync = true;
[email protected]21db9ef2014-05-16 02:06:272945const bool kGoodRemoteInstall = false;
[email protected]aa142702010-03-26 01:26:332946} // namespace
2947
treibe960e282015-09-11 10:38:082948// Test installing a pending extension (this goes through
2949// ExtensionService::UpdateExtension).
[email protected]d9a61e12012-11-14 02:43:472950TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
[email protected]eaa7dd182010-12-14 11:09:002951 InitializeEmptyExtensionService();
[email protected]21db9ef2014-05-16 02:06:272952 EXPECT_TRUE(
[email protected]6338fa32014-07-16 21:41:592953 service()->pending_extension_manager()->AddFromSync(
2954 kGoodId,
2955 GURL(kGoodUpdateURL),
treibe960e282015-09-11 10:38:082956 base::Version(kGoodVersion),
[email protected]6338fa32014-07-16 21:41:592957 &IsExtension,
mamir192d7882016-06-22 17:10:162958 kGoodRemoteInstall));
[email protected]f484f8d52014-06-12 08:38:182959 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332960
[email protected]f484f8d52014-06-12 08:38:182961 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]6cc7dbae2011-04-29 21:18:332962 UpdateExtension(kGoodId, path, ENABLED);
[email protected]aa142702010-03-26 01:26:332963
[email protected]f484f8d52014-06-12 08:38:182964 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]4416c5a2010-06-26 01:28:572965
David Bertoni58c113a2019-08-02 19:53:262966 const Extension* extension =
2967 registry()->GetExtensionById(kGoodId, ExtensionRegistry::COMPATIBILITY);
treibe960e282015-09-11 10:38:082968 EXPECT_TRUE(extension);
2969}
2970
2971TEST_F(ExtensionServiceTest, UpdatePendingExtensionWrongVersion) {
2972 InitializeEmptyExtensionService();
2973 base::Version other_version("0.1");
2974 ASSERT_TRUE(other_version.IsValid());
robpercivaldcd8b102016-01-25 19:39:002975 ASSERT_NE(other_version, base::Version(kGoodVersion));
treibe960e282015-09-11 10:38:082976 EXPECT_TRUE(
2977 service()->pending_extension_manager()->AddFromSync(
2978 kGoodId,
2979 GURL(kGoodUpdateURL),
2980 other_version,
2981 &IsExtension,
mamir192d7882016-06-22 17:10:162982 kGoodRemoteInstall));
treibe960e282015-09-11 10:38:082983 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2984
2985 base::FilePath path = data_dir().AppendASCII("good.crx");
2986 // After installation, the extension should be disabled, because it's missing
2987 // permissions.
2988 UpdateExtension(kGoodId, path, DISABLED);
2989
2990 EXPECT_TRUE(
2991 ExtensionPrefs::Get(profile())->DidExtensionEscalatePermissions(kGoodId));
2992
2993 // It should still have been installed though.
2994 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2995
David Bertoni58c113a2019-08-02 19:53:262996 const Extension* extension =
2997 registry()->GetExtensionById(kGoodId, ExtensionRegistry::COMPATIBILITY);
treibe960e282015-09-11 10:38:082998 EXPECT_TRUE(extension);
[email protected]aa142702010-03-26 01:26:332999}
3000
[email protected]7fa19f82010-12-21 19:40:083001namespace {
3002
[email protected]8f3bcbd2013-06-05 08:42:403003bool IsTheme(const Extension* extension) {
3004 return extension->is_theme();
[email protected]7fa19f82010-12-21 19:40:083005}
3006
3007} // namespace
3008
[email protected]11edd1e2010-07-21 00:14:503009// Test updating a pending theme.
rdevlin.croninaa55dfc2017-03-23 15:03:043010TEST_F(ExtensionServiceTest, UpdatePendingTheme) {
[email protected]eaa7dd182010-12-14 11:09:003011 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:183012 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
mamir192d7882016-06-22 17:10:163013 theme_crx, GURL(), base::Version(), &IsTheme, false));
[email protected]f484f8d52014-06-12 08:38:183014 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]11edd1e2010-07-21 00:14:503015
[email protected]f484f8d52014-06-12 08:38:183016 base::FilePath path = data_dir().AppendASCII("theme.crx");
[email protected]11edd1e2010-07-21 00:14:503017 UpdateExtension(theme_crx, path, ENABLED);
3018
[email protected]f484f8d52014-06-12 08:38:183019 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]11edd1e2010-07-21 00:14:503020
David Bertoni58c113a2019-08-02 19:53:263021 const Extension* extension =
3022 registry()->GetExtensionById(theme_crx, ExtensionRegistry::COMPATIBILITY);
[email protected]11edd1e2010-07-21 00:14:503023 ASSERT_TRUE(extension);
3024
[email protected]f484f8d52014-06-12 08:38:183025 EXPECT_FALSE(
3026 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3027 EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx));
[email protected]11edd1e2010-07-21 00:14:503028}
3029
[email protected]8ef78fd2010-08-19 17:14:323030// Test updating a pending CRX as if the source is an external extension
3031// with an update URL. In this case we don't know if the CRX is a theme
3032// or not.
rdevlin.cronin1428ea02017-03-22 21:15:323033TEST_F(ExtensionServiceTest, UpdatePendingExternalCrx) {
[email protected]eaa7dd182010-12-14 11:09:003034 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:183035 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]d8fd0fd2014-03-24 13:16:063036 theme_crx,
3037 std::string(),
3038 GURL(),
3039 Manifest::EXTERNAL_PREF_DOWNLOAD,
3040 Extension::NO_FLAGS,
[email protected]464213a2013-10-15 01:06:483041 false));
[email protected]8ef78fd2010-08-19 17:14:323042
[email protected]f484f8d52014-06-12 08:38:183043 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:323044
[email protected]f484f8d52014-06-12 08:38:183045 base::FilePath path = data_dir().AppendASCII("theme.crx");
[email protected]8ef78fd2010-08-19 17:14:323046 UpdateExtension(theme_crx, path, ENABLED);
3047
[email protected]f484f8d52014-06-12 08:38:183048 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:323049
David Bertoni58c113a2019-08-02 19:53:263050 const Extension* extension =
3051 registry()->GetExtensionById(theme_crx, ExtensionRegistry::COMPATIBILITY);
[email protected]8ef78fd2010-08-19 17:14:323052 ASSERT_TRUE(extension);
3053
[email protected]f484f8d52014-06-12 08:38:183054 EXPECT_FALSE(
3055 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3056 EXPECT_TRUE(service()->IsExtensionEnabled(extension->id()));
Devlin Cronineea1b7a2018-05-26 02:46:213057 EXPECT_FALSE(util::IsIncognitoEnabled(extension->id(), profile()));
[email protected]8ef78fd2010-08-19 17:14:323058}
3059
[email protected]1afaf2a52010-11-02 19:29:173060// Test updating a pending CRX as if the source is an external extension
3061// with an update URL. The external update should overwrite a sync update,
3062// but a sync update should not overwrite a non-sync update.
[email protected]d9a61e12012-11-14 02:43:473063TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
[email protected]eaa7dd182010-12-14 11:09:003064 InitializeEmptyExtensionService();
[email protected]1afaf2a52010-11-02 19:29:173065
3066 // Add a crx to be installed from the update mechanism.
[email protected]21db9ef2014-05-16 02:06:273067 EXPECT_TRUE(
[email protected]6338fa32014-07-16 21:41:593068 service()->pending_extension_manager()->AddFromSync(
3069 kGoodId,
3070 GURL(kGoodUpdateURL),
treibe960e282015-09-11 10:38:083071 base::Version(),
[email protected]6338fa32014-07-16 21:41:593072 &IsExtension,
mamir192d7882016-06-22 17:10:163073 kGoodRemoteInstall));
[email protected]1afaf2a52010-11-02 19:29:173074
3075 // Check that there is a pending crx, with is_from_sync set to true.
Devlin Cronineea1b7a2018-05-26 02:46:213076 const PendingExtensionInfo* pending_extension_info;
[email protected]f484f8d52014-06-12 08:38:183077 ASSERT_TRUE((pending_extension_info =
3078 service()->pending_extension_manager()->GetById(kGoodId)));
[email protected]51a3bf8b2012-06-08 22:53:063079 EXPECT_TRUE(pending_extension_info->is_from_sync());
[email protected]1afaf2a52010-11-02 19:29:173080
3081 // Add a crx to be updated, with the same ID, from a non-sync source.
[email protected]f484f8d52014-06-12 08:38:183082 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]d8fd0fd2014-03-24 13:16:063083 kGoodId,
3084 std::string(),
3085 GURL(kGoodUpdateURL),
3086 Manifest::EXTERNAL_PREF_DOWNLOAD,
3087 Extension::NO_FLAGS,
3088 false));
[email protected]1afaf2a52010-11-02 19:29:173089
3090 // Check that there is a pending crx, with is_from_sync set to false.
[email protected]f484f8d52014-06-12 08:38:183091 ASSERT_TRUE((pending_extension_info =
3092 service()->pending_extension_manager()->GetById(kGoodId)));
[email protected]51a3bf8b2012-06-08 22:53:063093 EXPECT_FALSE(pending_extension_info->is_from_sync());
[email protected]1d5e58b2013-01-31 08:41:403094 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
[email protected]51a3bf8b2012-06-08 22:53:063095 pending_extension_info->install_source());
[email protected]1afaf2a52010-11-02 19:29:173096
3097 // Add a crx to be installed from the update mechanism.
[email protected]21db9ef2014-05-16 02:06:273098 EXPECT_FALSE(
[email protected]6338fa32014-07-16 21:41:593099 service()->pending_extension_manager()->AddFromSync(
3100 kGoodId,
3101 GURL(kGoodUpdateURL),
treibe960e282015-09-11 10:38:083102 base::Version(),
[email protected]6338fa32014-07-16 21:41:593103 &IsExtension,
mamir192d7882016-06-22 17:10:163104 kGoodRemoteInstall));
[email protected]1afaf2a52010-11-02 19:29:173105
3106 // Check that the external, non-sync update was not overridden.
[email protected]f484f8d52014-06-12 08:38:183107 ASSERT_TRUE((pending_extension_info =
3108 service()->pending_extension_manager()->GetById(kGoodId)));
[email protected]51a3bf8b2012-06-08 22:53:063109 EXPECT_FALSE(pending_extension_info->is_from_sync());
[email protected]1d5e58b2013-01-31 08:41:403110 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
[email protected]51a3bf8b2012-06-08 22:53:063111 pending_extension_info->install_source());
[email protected]1afaf2a52010-11-02 19:29:173112}
3113
[email protected]8ef78fd2010-08-19 17:14:323114// Updating a theme should fail if the updater is explicitly told that
3115// the CRX is not a theme.
[email protected]d9a61e12012-11-14 02:43:473116TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
[email protected]eaa7dd182010-12-14 11:09:003117 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:183118 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
mamir192d7882016-06-22 17:10:163119 theme_crx, GURL(), base::Version(), &IsExtension, false));
[email protected]8ef78fd2010-08-19 17:14:323120
[email protected]f484f8d52014-06-12 08:38:183121 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:323122
[email protected]f484f8d52014-06-12 08:38:183123 base::FilePath path = data_dir().AppendASCII("theme.crx");
[email protected]8ef78fd2010-08-19 17:14:323124 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3125
[email protected]f484f8d52014-06-12 08:38:183126 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:323127
David Bertoni58c113a2019-08-02 19:53:263128 const Extension* extension =
3129 registry()->GetExtensionById(theme_crx, ExtensionRegistry::COMPATIBILITY);
[email protected]8ef78fd2010-08-19 17:14:323130 ASSERT_FALSE(extension);
3131}
3132
[email protected]aa142702010-03-26 01:26:333133// TODO(akalin): Test updating a pending extension non-silently once
3134// we can mock out ExtensionInstallUI and inject our version into
3135// UpdateExtension().
3136
[email protected]7fa19f82010-12-21 19:40:083137// Test updating a pending extension which fails the should-install test.
[email protected]d9a61e12012-11-14 02:43:473138TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
[email protected]eaa7dd182010-12-14 11:09:003139 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:333140 // Add pending extension with a flipped is_theme.
[email protected]21db9ef2014-05-16 02:06:273141 EXPECT_TRUE(
[email protected]6338fa32014-07-16 21:41:593142 service()->pending_extension_manager()->AddFromSync(
3143 kGoodId,
3144 GURL(kGoodUpdateURL),
treibe960e282015-09-11 10:38:083145 base::Version(),
[email protected]6338fa32014-07-16 21:41:593146 &IsTheme,
mamir192d7882016-06-22 17:10:163147 kGoodRemoteInstall));
[email protected]f484f8d52014-06-12 08:38:183148 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:333149
[email protected]f484f8d52014-06-12 08:38:183150 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:573151 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:333152
3153 // TODO(akalin): Figure out how to check that the extensions
3154 // directory is cleaned up properly in OnExtensionInstalled().
3155
[email protected]f484f8d52014-06-12 08:38:183156 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:333157}
3158
[email protected]11edd1e2010-07-21 00:14:503159// TODO(akalin): Figure out how to test that installs of pending
3160// unsyncable extensions are blocked.
3161
[email protected]aa142702010-03-26 01:26:333162// Test updating a pending extension for one that is not pending.
[email protected]d9a61e12012-11-14 02:43:473163TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
[email protected]eaa7dd182010-12-14 11:09:003164 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:333165
[email protected]f484f8d52014-06-12 08:38:183166 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:573167 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:333168
[email protected]f484f8d52014-06-12 08:38:183169 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:333170}
3171
3172// Test updating a pending extension for one that is already
3173// installed.
[email protected]d9a61e12012-11-14 02:43:473174TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
[email protected]eaa7dd182010-12-14 11:09:003175 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:333176
[email protected]f484f8d52014-06-12 08:38:183177 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503178 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]f484f8d52014-06-12 08:38:183179 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]aa142702010-03-26 01:26:333180
[email protected]8ef78fd2010-08-19 17:14:323181 EXPECT_FALSE(good->is_theme());
3182
[email protected]b2907fd2011-03-25 16:43:373183 // Use AddExtensionImpl() as AddFrom*() would balk.
[email protected]f484f8d52014-06-12 08:38:183184 service()->pending_extension_manager()->AddExtensionImpl(
Devlin Cronineea1b7a2018-05-26 02:46:213185 good->id(), std::string(), ManifestURL::GetUpdateURL(good),
3186 base::Version(), &IsExtension, kGoodIsFromSync, Manifest::INTERNAL,
3187 Extension::NO_FLAGS, false, kGoodRemoteInstall);
[email protected]6cc7dbae2011-04-29 21:18:333188 UpdateExtension(good->id(), path, ENABLED);
[email protected]aa142702010-03-26 01:26:333189
[email protected]f484f8d52014-06-12 08:38:183190 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]e957fe52009-06-23 16:51:053191}
3192
[email protected]3f2a2fa2013-09-24 02:55:253193#if defined(ENABLE_BLACKLIST_TESTS)
3194// Tests blacklisting then unblacklisting extensions after the service has been
3195// initialized.
[email protected]7d9b4e32013-10-25 06:11:543196TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
Devlin Cronineea1b7a2018-05-26 02:46:213197 TestBlacklist test_blacklist;
[email protected]3f2a2fa2013-09-24 02:55:253198 // A profile with 3 extensions installed: good0, good1, and good2.
3199 InitializeGoodInstalledExtensionService();
[email protected]f484f8d52014-06-12 08:38:183200 test_blacklist.Attach(service()->blacklist_);
3201 service()->Init();
[email protected]e636c812013-09-23 05:51:083202
Devlin Cronineea1b7a2018-05-26 02:46:213203 const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
3204 const ExtensionSet& blacklisted_extensions =
[email protected]f484f8d52014-06-12 08:38:183205 registry()->blacklisted_extensions();
[email protected]e636c812013-09-23 05:51:083206
[email protected]5fdfa562013-12-27 17:43:593207 EXPECT_TRUE(enabled_extensions.Contains(good0) &&
3208 !blacklisted_extensions.Contains(good0));
3209 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3210 !blacklisted_extensions.Contains(good1));
3211 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3212 !blacklisted_extensions.Contains(good2));
[email protected]e636c812013-09-23 05:51:083213
[email protected]3f2a2fa2013-09-24 02:55:253214 EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
[email protected]e636c812013-09-23 05:51:083215 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
[email protected]3f2a2fa2013-09-24 02:55:253216 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3217 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3218
3219 // Blacklist good0 and good1 (and an invalid extension ID).
Devlin Cronineea1b7a2018-05-26 02:46:213220 test_blacklist.SetBlacklistState(good0, BLACKLISTED_MALWARE, true);
3221 test_blacklist.SetBlacklistState(good1, BLACKLISTED_MALWARE, true);
3222 test_blacklist.SetBlacklistState("invalid_id", BLACKLISTED_MALWARE, true);
Gabriel Charette01507a22017-09-27 21:30:083223 content::RunAllTasksUntilIdle();
[email protected]3f2a2fa2013-09-24 02:55:253224
[email protected]5fdfa562013-12-27 17:43:593225 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3226 blacklisted_extensions.Contains(good0));
3227 EXPECT_TRUE(!enabled_extensions.Contains(good1) &&
3228 blacklisted_extensions.Contains(good1));
3229 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3230 !blacklisted_extensions.Contains(good2));
[email protected]3f2a2fa2013-09-24 02:55:253231
3232 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3233 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
3234 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3235 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3236
3237 // Un-blacklist good1 and blacklist good2.
[email protected]f71b582c2014-01-10 17:03:153238 test_blacklist.Clear(false);
Devlin Cronineea1b7a2018-05-26 02:46:213239 test_blacklist.SetBlacklistState(good0, BLACKLISTED_MALWARE, true);
3240 test_blacklist.SetBlacklistState(good2, BLACKLISTED_MALWARE, true);
3241 test_blacklist.SetBlacklistState("invalid_id", BLACKLISTED_MALWARE, true);
Gabriel Charette01507a22017-09-27 21:30:083242 content::RunAllTasksUntilIdle();
[email protected]3f2a2fa2013-09-24 02:55:253243
[email protected]5fdfa562013-12-27 17:43:593244 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3245 blacklisted_extensions.Contains(good0));
3246 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3247 !blacklisted_extensions.Contains(good1));
3248 EXPECT_TRUE(!enabled_extensions.Contains(good2) &&
3249 blacklisted_extensions.Contains(good2));
[email protected]3f2a2fa2013-09-24 02:55:253250
3251 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3252 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3253 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
[email protected]e2194742010-08-12 05:54:343254 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
[email protected]6b75ec32009-08-14 06:37:183255}
[email protected]3f2a2fa2013-09-24 02:55:253256#endif // defined(ENABLE_BLACKLIST_TESTS)
[email protected]6b75ec32009-08-14 06:37:183257
[email protected]3f2a2fa2013-09-24 02:55:253258#if defined(ENABLE_BLACKLIST_TESTS)
3259// Tests trying to install a blacklisted extension.
[email protected]e0cbfc42013-11-07 00:10:103260TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
[email protected]3f2a2fa2013-09-24 02:55:253261 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3262 new FakeSafeBrowsingDatabaseManager(true));
3263 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3264
[email protected]1747eac02013-09-23 10:58:423265 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:183266 service()->Init();
[email protected]1747eac02013-09-23 10:58:423267
[email protected]3f2a2fa2013-09-24 02:55:253268 // After blacklisting good_crx, we cannot install it.
3269 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
Gabriel Charette01507a22017-09-27 21:30:083270 content::RunAllTasksUntilIdle();
[email protected]1747eac02013-09-23 10:58:423271
[email protected]f484f8d52014-06-12 08:38:183272 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]9f3c8532013-07-31 19:52:073273 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3274 // decide to install this silently. Somebody should fix these tests, all
3275 // 6,000 lines of them. Hah!
3276 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
[email protected]f484f8d52014-06-12 08:38:183277 EXPECT_EQ(0u, registry()->enabled_extensions().size());
[email protected]6b75ec32009-08-14 06:37:183278}
[email protected]3f2a2fa2013-09-24 02:55:253279#endif // defined(ENABLE_BLACKLIST_TESTS)
[email protected]6b75ec32009-08-14 06:37:183280
[email protected]3f2a2fa2013-09-24 02:55:253281#if defined(ENABLE_BLACKLIST_TESTS)
atuchin6dc7c442016-07-20 07:04:343282// Tests that previously blacklisted extension will be enabled if it is removed
3283// from the blacklist. Also checks that all blacklisted preferences will be
3284// cleared in that case.
3285TEST_F(ExtensionServiceTest, RemoveExtensionFromBlacklist) {
Devlin Cronineea1b7a2018-05-26 02:46:213286 TestBlacklist test_blacklist;
atuchin6dc7c442016-07-20 07:04:343287 // A profile with 3 extensions installed: good0, good1, and good2.
3288 InitializeGoodInstalledExtensionService();
3289 test_blacklist.Attach(service()->blacklist_);
3290 service()->Init();
3291
3292 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
Devlin Cronineea1b7a2018-05-26 02:46:213293 TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile()),
3294 good0);
atuchin6dc7c442016-07-20 07:04:343295
3296 // Add the extension to the blacklist.
Devlin Cronineea1b7a2018-05-26 02:46:213297 test_blacklist.SetBlacklistState(good0, BLACKLISTED_MALWARE, true);
atuchin6dc7c442016-07-20 07:04:343298 observer.WaitForExtensionUnloaded();
3299
3300 // The extension should be disabled, both "blacklist" and "blacklist_state"
3301 // prefs should be set.
vmpstrae72b082016-07-25 21:55:473302 auto* prefs = ExtensionPrefs::Get(profile());
atuchin6dc7c442016-07-20 07:04:343303 EXPECT_FALSE(registry()->enabled_extensions().Contains(good0));
3304 EXPECT_TRUE(prefs->IsExtensionBlacklisted(good0));
Devlin Cronineea1b7a2018-05-26 02:46:213305 EXPECT_EQ(BLACKLISTED_MALWARE, prefs->GetExtensionBlacklistState(good0));
atuchin6dc7c442016-07-20 07:04:343306
3307 // Remove the extension from the blacklist.
Devlin Cronineea1b7a2018-05-26 02:46:213308 test_blacklist.SetBlacklistState(good0, NOT_BLACKLISTED, true);
atuchin6dc7c442016-07-20 07:04:343309 observer.WaitForExtensionLoaded()->id();
3310
3311 // The extension should be enabled, both "blacklist" and "blacklist_state"
3312 // should be cleared.
3313 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3314 EXPECT_FALSE(prefs->IsExtensionBlacklisted(good0));
Devlin Cronineea1b7a2018-05-26 02:46:213315 EXPECT_EQ(NOT_BLACKLISTED, prefs->GetExtensionBlacklistState(good0));
atuchin6dc7c442016-07-20 07:04:343316}
3317#endif // defined(ENABLE_BLACKLIST_TESTS)
3318
3319#if defined(ENABLE_BLACKLIST_TESTS)
[email protected]4ee07c62012-08-21 12:40:423320// Unload blacklisted extension on policy change.
[email protected]d9a61e12012-11-14 02:43:473321TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
Devlin Cronineea1b7a2018-05-26 02:46:213322 TestBlacklist test_blacklist;
[email protected]3f2a2fa2013-09-24 02:55:253323
3324 // A profile with no extensions installed.
binjin1569c9b2014-09-05 13:33:183325 InitializeEmptyExtensionServiceWithTestingPrefs();
[email protected]f484f8d52014-06-12 08:38:183326 test_blacklist.Attach(service()->blacklist_);
[email protected]3f2a2fa2013-09-24 02:55:253327
[email protected]f484f8d52014-06-12 08:38:183328 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]4ee07c62012-08-21 12:40:423329
3330 const Extension* good = InstallCRX(path, INSTALL_NEW);
3331 EXPECT_EQ(good_crx, good->id());
3332 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]f484f8d52014-06-12 08:38:183333 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]4ee07c62012-08-21 12:40:423334
binjinb2454382014-09-22 15:17:433335 {
3336 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3337 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3338 }
[email protected]4ee07c62012-08-21 12:40:423339
Devlin Cronineea1b7a2018-05-26 02:46:213340 test_blacklist.SetBlacklistState(good_crx, BLACKLISTED_MALWARE, true);
Gabriel Charette01507a22017-09-27 21:30:083341 content::RunAllTasksUntilIdle();
[email protected]4ee07c62012-08-21 12:40:423342
[email protected]695b5712012-12-06 23:55:283343 // The good_crx is blacklisted and the whitelist doesn't negate it.
[email protected]3f2a2fa2013-09-24 02:55:253344 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
[email protected]f484f8d52014-06-12 08:38:183345 EXPECT_EQ(0u, registry()->enabled_extensions().size());
[email protected]4ee07c62012-08-21 12:40:423346}
[email protected]3f2a2fa2013-09-24 02:55:253347#endif // defined(ENABLE_BLACKLIST_TESTS)
[email protected]4ee07c62012-08-21 12:40:423348
[email protected]3f2a2fa2013-09-24 02:55:253349#if defined(ENABLE_BLACKLIST_TESTS)
3350// Tests that a blacklisted extension is eventually unloaded on startup, if it
3351// wasn't already.
[email protected]e0cbfc42013-11-07 00:10:103352TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
Devlin Cronineea1b7a2018-05-26 02:46:213353 TestBlacklist test_blacklist;
[email protected]6b75ec32009-08-14 06:37:183354
[email protected]3f2a2fa2013-09-24 02:55:253355 // A profile with 3 extensions installed: good0, good1, and good2.
3356 InitializeGoodInstalledExtensionService();
[email protected]f484f8d52014-06-12 08:38:183357 test_blacklist.Attach(service()->blacklist_);
[email protected]fdd679b2012-11-15 20:49:393358
[email protected]3f2a2fa2013-09-24 02:55:253359 // Blacklist good1 before the service initializes.
Devlin Cronineea1b7a2018-05-26 02:46:213360 test_blacklist.SetBlacklistState(good1, BLACKLISTED_MALWARE, false);
[email protected]6b75ec32009-08-14 06:37:183361
3362 // Load extensions.
[email protected]f484f8d52014-06-12 08:38:183363 service()->Init();
[email protected]3f2a2fa2013-09-24 02:55:253364 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet
[email protected]6b75ec32009-08-14 06:37:183365
Gabriel Charette01507a22017-09-27 21:30:083366 content::RunAllTasksUntilIdle();
[email protected]6b75ec32009-08-14 06:37:183367
[email protected]f484f8d52014-06-12 08:38:183368 ASSERT_EQ(1u, registry()->blacklisted_extensions().size());
3369 ASSERT_EQ(2u, registry()->enabled_extensions().size());
[email protected]5fdfa562013-12-27 17:43:593370
[email protected]f484f8d52014-06-12 08:38:183371 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
3372 ASSERT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3373 ASSERT_TRUE(registry()->enabled_extensions().Contains(good2));
[email protected]6b75ec32009-08-14 06:37:183374}
[email protected]3f2a2fa2013-09-24 02:55:253375#endif // defined(ENABLE_BLACKLIST_TESTS)
3376
3377#if defined(ENABLE_BLACKLIST_TESTS)
3378// Tests extensions blacklisted in prefs on startup; one still blacklisted by
3379// safe browsing, the other not. The not-blacklisted one should recover.
3380TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
Devlin Cronineea1b7a2018-05-26 02:46:213381 TestBlacklist test_blacklist;
[email protected]3f2a2fa2013-09-24 02:55:253382
3383 InitializeGoodInstalledExtensionService();
[email protected]f484f8d52014-06-12 08:38:183384 test_blacklist.Attach(service()->blacklist_);
atuchin6dc7c442016-07-20 07:04:343385 ExtensionPrefs::Get(profile())->SetExtensionBlacklistState(
Devlin Cronineea1b7a2018-05-26 02:46:213386 good0, BLACKLISTED_MALWARE);
atuchin6dc7c442016-07-20 07:04:343387 ExtensionPrefs::Get(profile())->SetExtensionBlacklistState(
Devlin Cronineea1b7a2018-05-26 02:46:213388 good1, BLACKLISTED_MALWARE);
[email protected]3f2a2fa2013-09-24 02:55:253389
Devlin Cronineea1b7a2018-05-26 02:46:213390 test_blacklist.SetBlacklistState(good1, BLACKLISTED_MALWARE, false);
[email protected]3f2a2fa2013-09-24 02:55:253391
[email protected]27e528322014-05-27 20:54:303392 // Extension service hasn't loaded yet, but IsExtensionEnabled reads out of
3393 // prefs. Ensure it takes into account the blacklist state (crbug.com/373842).
[email protected]f484f8d52014-06-12 08:38:183394 EXPECT_FALSE(service()->IsExtensionEnabled(good0));
3395 EXPECT_FALSE(service()->IsExtensionEnabled(good1));
3396 EXPECT_TRUE(service()->IsExtensionEnabled(good2));
[email protected]27e528322014-05-27 20:54:303397
[email protected]f484f8d52014-06-12 08:38:183398 service()->Init();
[email protected]3f2a2fa2013-09-24 02:55:253399
[email protected]f484f8d52014-06-12 08:38:183400 EXPECT_EQ(2u, registry()->blacklisted_extensions().size());
3401 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]3f2a2fa2013-09-24 02:55:253402
[email protected]f484f8d52014-06-12 08:38:183403 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good0));
3404 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3405 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
[email protected]3f2a2fa2013-09-24 02:55:253406
3407 // Give time for the blacklist to update.
Gabriel Charette01507a22017-09-27 21:30:083408 content::RunAllTasksUntilIdle();
[email protected]3f2a2fa2013-09-24 02:55:253409
[email protected]f484f8d52014-06-12 08:38:183410 EXPECT_EQ(1u, registry()->blacklisted_extensions().size());
3411 EXPECT_EQ(2u, registry()->enabled_extensions().size());
[email protected]3f2a2fa2013-09-24 02:55:253412
[email protected]f484f8d52014-06-12 08:38:183413 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3414 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3415 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
[email protected]3f2a2fa2013-09-24 02:55:253416}
3417#endif // defined(ENABLE_BLACKLIST_TESTS)
[email protected]6b75ec32009-08-14 06:37:183418
[email protected]2d19eb6e2014-01-27 17:30:003419#if defined(ENABLE_BLACKLIST_TESTS)
3420// Extension is added to blacklist with BLACKLISTED_POTENTIALLY_UNWANTED state
3421// after it is installed. It is then successfully re-enabled by the user.
3422TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) {
Devlin Cronineea1b7a2018-05-26 02:46:213423 TestBlacklist test_blacklist;
[email protected]2d19eb6e2014-01-27 17:30:003424 // A profile with 3 extensions installed: good0, good1, and good2.
3425 InitializeGoodInstalledExtensionService();
[email protected]f484f8d52014-06-12 08:38:183426 test_blacklist.Attach(service()->blacklist_);
3427 service()->Init();
[email protected]2d19eb6e2014-01-27 17:30:003428
Devlin Cronineea1b7a2018-05-26 02:46:213429 const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
3430 const ExtensionSet& disabled_extensions = registry()->disabled_extensions();
[email protected]2d19eb6e2014-01-27 17:30:003431
3432 EXPECT_TRUE(enabled_extensions.Contains(good0));
3433 EXPECT_TRUE(enabled_extensions.Contains(good1));
3434 EXPECT_TRUE(enabled_extensions.Contains(good2));
3435
3436 // Blacklist good0 and good1 (and an invalid extension ID).
Devlin Cronineea1b7a2018-05-26 02:46:213437 test_blacklist.SetBlacklistState(good0, BLACKLISTED_CWS_POLICY_VIOLATION,
3438 true);
3439 test_blacklist.SetBlacklistState(good1, BLACKLISTED_POTENTIALLY_UNWANTED,
3440 true);
3441 test_blacklist.SetBlacklistState("invalid_id", BLACKLISTED_MALWARE, true);
Gabriel Charette01507a22017-09-27 21:30:083442 content::RunAllTasksUntilIdle();
[email protected]2d19eb6e2014-01-27 17:30:003443
3444 EXPECT_FALSE(enabled_extensions.Contains(good0));
3445 EXPECT_TRUE(disabled_extensions.Contains(good0));
3446 EXPECT_FALSE(enabled_extensions.Contains(good1));
3447 EXPECT_TRUE(disabled_extensions.Contains(good1));
3448 EXPECT_TRUE(enabled_extensions.Contains(good2));
3449 EXPECT_FALSE(disabled_extensions.Contains(good2));
3450
Devlin Cronineea1b7a2018-05-26 02:46:213451 ValidateIntegerPref(good0, "blacklist_state",
3452 BLACKLISTED_CWS_POLICY_VIOLATION);
3453 ValidateIntegerPref(good1, "blacklist_state",
3454 BLACKLISTED_POTENTIALLY_UNWANTED);
[email protected]2d19eb6e2014-01-27 17:30:003455
3456 // Now user enables good0.
[email protected]f484f8d52014-06-12 08:38:183457 service()->EnableExtension(good0);
[email protected]2d19eb6e2014-01-27 17:30:003458
3459 EXPECT_TRUE(enabled_extensions.Contains(good0));
3460 EXPECT_FALSE(disabled_extensions.Contains(good0));
3461 EXPECT_FALSE(enabled_extensions.Contains(good1));
3462 EXPECT_TRUE(disabled_extensions.Contains(good1));
3463
3464 // Remove extensions from blacklist.
Devlin Cronineea1b7a2018-05-26 02:46:213465 test_blacklist.SetBlacklistState(good0, NOT_BLACKLISTED, true);
3466 test_blacklist.SetBlacklistState(good1, NOT_BLACKLISTED, true);
Gabriel Charette01507a22017-09-27 21:30:083467 content::RunAllTasksUntilIdle();
[email protected]2d19eb6e2014-01-27 17:30:003468
3469 // All extensions are enabled.
3470 EXPECT_TRUE(enabled_extensions.Contains(good0));
3471 EXPECT_FALSE(disabled_extensions.Contains(good0));
3472 EXPECT_TRUE(enabled_extensions.Contains(good1));
3473 EXPECT_FALSE(disabled_extensions.Contains(good1));
3474 EXPECT_TRUE(enabled_extensions.Contains(good2));
3475 EXPECT_FALSE(disabled_extensions.Contains(good2));
3476}
3477#endif // defined(ENABLE_BLACKLIST_TESTS)
3478
3479#if defined(ENABLE_BLACKLIST_TESTS)
3480// When extension is removed from greylist, do not re-enable it if it is
3481// disabled by user.
3482TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) {
Devlin Cronineea1b7a2018-05-26 02:46:213483 TestBlacklist test_blacklist;
[email protected]2d19eb6e2014-01-27 17:30:003484 // A profile with 3 extensions installed: good0, good1, and good2.
3485 InitializeGoodInstalledExtensionService();
[email protected]f484f8d52014-06-12 08:38:183486 test_blacklist.Attach(service()->blacklist_);
3487 service()->Init();
[email protected]2d19eb6e2014-01-27 17:30:003488
Devlin Cronineea1b7a2018-05-26 02:46:213489 const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
3490 const ExtensionSet& disabled_extensions = registry()->disabled_extensions();
[email protected]2d19eb6e2014-01-27 17:30:003491
3492 // Manually disable.
Devlin Cronineea1b7a2018-05-26 02:46:213493 service()->DisableExtension(good0, disable_reason::DISABLE_USER_ACTION);
[email protected]2d19eb6e2014-01-27 17:30:003494
Devlin Cronineea1b7a2018-05-26 02:46:213495 test_blacklist.SetBlacklistState(good0, BLACKLISTED_CWS_POLICY_VIOLATION,
3496 true);
3497 test_blacklist.SetBlacklistState(good1, BLACKLISTED_POTENTIALLY_UNWANTED,
3498 true);
3499 test_blacklist.SetBlacklistState(good2, BLACKLISTED_SECURITY_VULNERABILITY,
3500 true);
Gabriel Charette01507a22017-09-27 21:30:083501 content::RunAllTasksUntilIdle();
[email protected]2d19eb6e2014-01-27 17:30:003502
3503 // All extensions disabled.
3504 EXPECT_FALSE(enabled_extensions.Contains(good0));
3505 EXPECT_TRUE(disabled_extensions.Contains(good0));
3506 EXPECT_FALSE(enabled_extensions.Contains(good1));
3507 EXPECT_TRUE(disabled_extensions.Contains(good1));
3508 EXPECT_FALSE(enabled_extensions.Contains(good2));
3509 EXPECT_TRUE(disabled_extensions.Contains(good2));
3510
3511 // Greylisted extension can be enabled.
[email protected]f484f8d52014-06-12 08:38:183512 service()->EnableExtension(good1);
[email protected]2d19eb6e2014-01-27 17:30:003513 EXPECT_TRUE(enabled_extensions.Contains(good1));
3514 EXPECT_FALSE(disabled_extensions.Contains(good1));
3515
3516 // good1 is now manually disabled.
Devlin Cronineea1b7a2018-05-26 02:46:213517 service()->DisableExtension(good1, disable_reason::DISABLE_USER_ACTION);
[email protected]2d19eb6e2014-01-27 17:30:003518 EXPECT_FALSE(enabled_extensions.Contains(good1));
3519 EXPECT_TRUE(disabled_extensions.Contains(good1));
3520
3521 // Remove extensions from blacklist.
Devlin Cronineea1b7a2018-05-26 02:46:213522 test_blacklist.SetBlacklistState(good0, NOT_BLACKLISTED, true);
3523 test_blacklist.SetBlacklistState(good1, NOT_BLACKLISTED, true);
3524 test_blacklist.SetBlacklistState(good2, NOT_BLACKLISTED, true);
Gabriel Charette01507a22017-09-27 21:30:083525 content::RunAllTasksUntilIdle();
[email protected]2d19eb6e2014-01-27 17:30:003526
3527 // good0 and good1 remain disabled.
3528 EXPECT_FALSE(enabled_extensions.Contains(good0));
3529 EXPECT_TRUE(disabled_extensions.Contains(good0));
3530 EXPECT_FALSE(enabled_extensions.Contains(good1));
3531 EXPECT_TRUE(disabled_extensions.Contains(good1));
3532 EXPECT_TRUE(enabled_extensions.Contains(good2));
3533 EXPECT_FALSE(disabled_extensions.Contains(good2));
3534}
3535#endif // defined(ENABLE_BLACKLIST_TESTS)
3536
3537#if defined(ENABLE_BLACKLIST_TESTS)
3538// Blacklisted extension with unknown state are not enabled/disabled.
3539TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) {
Devlin Cronineea1b7a2018-05-26 02:46:213540 TestBlacklist test_blacklist;
[email protected]2d19eb6e2014-01-27 17:30:003541 // A profile with 3 extensions installed: good0, good1, and good2.
3542 InitializeGoodInstalledExtensionService();
[email protected]f484f8d52014-06-12 08:38:183543 test_blacklist.Attach(service()->blacklist_);
3544 service()->Init();
[email protected]2d19eb6e2014-01-27 17:30:003545
Devlin Cronineea1b7a2018-05-26 02:46:213546 const ExtensionSet& enabled_extensions = registry()->enabled_extensions();
3547 const ExtensionSet& disabled_extensions = registry()->disabled_extensions();
[email protected]2d19eb6e2014-01-27 17:30:003548
Devlin Cronineea1b7a2018-05-26 02:46:213549 test_blacklist.SetBlacklistState(good0, BLACKLISTED_CWS_POLICY_VIOLATION,
3550 true);
3551 test_blacklist.SetBlacklistState(good1, BLACKLISTED_POTENTIALLY_UNWANTED,
3552 true);
Gabriel Charette01507a22017-09-27 21:30:083553 content::RunAllTasksUntilIdle();
[email protected]2d19eb6e2014-01-27 17:30:003554
3555 EXPECT_FALSE(enabled_extensions.Contains(good0));
3556 EXPECT_TRUE(disabled_extensions.Contains(good0));
3557 EXPECT_FALSE(enabled_extensions.Contains(good1));
3558 EXPECT_TRUE(disabled_extensions.Contains(good1));
3559 EXPECT_TRUE(enabled_extensions.Contains(good2));
3560 EXPECT_FALSE(disabled_extensions.Contains(good2));
3561
Devlin Cronineea1b7a2018-05-26 02:46:213562 test_blacklist.SetBlacklistState(good0, NOT_BLACKLISTED, true);
3563 test_blacklist.SetBlacklistState(good1, BLACKLISTED_UNKNOWN, true);
3564 test_blacklist.SetBlacklistState(good2, BLACKLISTED_UNKNOWN, true);
Gabriel Charette01507a22017-09-27 21:30:083565 content::RunAllTasksUntilIdle();
[email protected]2d19eb6e2014-01-27 17:30:003566
3567 // good0 re-enabled, other remain as they were.
3568 EXPECT_TRUE(enabled_extensions.Contains(good0));
3569 EXPECT_FALSE(disabled_extensions.Contains(good0));
3570 EXPECT_FALSE(enabled_extensions.Contains(good1));
3571 EXPECT_TRUE(disabled_extensions.Contains(good1));
3572 EXPECT_TRUE(enabled_extensions.Contains(good2));
3573 EXPECT_FALSE(disabled_extensions.Contains(good2));
3574}
[email protected]757d60a2014-05-23 00:11:443575
3576// Tests that blacklisted extensions cannot be reloaded, both those loaded
3577// before and after extension service startup.
3578TEST_F(ExtensionServiceTest, ReloadBlacklistedExtension) {
Devlin Cronineea1b7a2018-05-26 02:46:213579 TestBlacklist test_blacklist;
[email protected]757d60a2014-05-23 00:11:443580
3581 InitializeGoodInstalledExtensionService();
[email protected]f484f8d52014-06-12 08:38:183582 test_blacklist.Attach(service()->blacklist_);
[email protected]757d60a2014-05-23 00:11:443583
Devlin Cronineea1b7a2018-05-26 02:46:213584 test_blacklist.SetBlacklistState(good1, BLACKLISTED_MALWARE, false);
[email protected]f484f8d52014-06-12 08:38:183585 service()->Init();
Devlin Cronineea1b7a2018-05-26 02:46:213586 test_blacklist.SetBlacklistState(good2, BLACKLISTED_MALWARE, false);
Gabriel Charette01507a22017-09-27 21:30:083587 content::RunAllTasksUntilIdle();
[email protected]757d60a2014-05-23 00:11:443588
[email protected]f484f8d52014-06-12 08:38:183589 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
[email protected]757d60a2014-05-23 00:11:443590 EXPECT_EQ(StringSet(good1, good2),
[email protected]f484f8d52014-06-12 08:38:183591 registry()->blacklisted_extensions().GetIDs());
[email protected]757d60a2014-05-23 00:11:443592
[email protected]f484f8d52014-06-12 08:38:183593 service()->ReloadExtension(good1);
3594 service()->ReloadExtension(good2);
Gabriel Charette01507a22017-09-27 21:30:083595 content::RunAllTasksUntilIdle();
[email protected]757d60a2014-05-23 00:11:443596
[email protected]f484f8d52014-06-12 08:38:183597 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
[email protected]757d60a2014-05-23 00:11:443598 EXPECT_EQ(StringSet(good1, good2),
[email protected]f484f8d52014-06-12 08:38:183599 registry()->blacklisted_extensions().GetIDs());
[email protected]757d60a2014-05-23 00:11:443600}
[email protected]2d19eb6e2014-01-27 17:30:003601#endif // defined(ENABLE_BLACKLIST_TESTS)
3602
mlerman6a37b6a42014-11-26 22:10:533603// Tests blocking then unblocking enabled extensions after the service has been
3604// initialized.
3605TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledExtension) {
3606 InitializeGoodInstalledExtensionService();
3607 service()->Init();
3608
3609 AssertExtensionBlocksAndUnblocks(true, good0);
3610}
3611
3612// Tests blocking then unblocking disabled extensions after the service has been
3613// initialized.
3614TEST_F(ExtensionServiceTest, BlockAndUnblockDisabledExtension) {
3615 InitializeGoodInstalledExtensionService();
3616 service()->Init();
3617
Devlin Cronineea1b7a2018-05-26 02:46:213618 service()->DisableExtension(good0, disable_reason::DISABLE_RELOAD);
mlerman6a37b6a42014-11-26 22:10:533619
3620 AssertExtensionBlocksAndUnblocks(true, good0);
3621}
3622
3623// Tests blocking then unblocking terminated extensions after the service has
3624// been initialized.
3625TEST_F(ExtensionServiceTest, BlockAndUnblockTerminatedExtension) {
3626 InitializeGoodInstalledExtensionService();
3627 service()->Init();
3628
3629 TerminateExtension(good0);
3630
3631 AssertExtensionBlocksAndUnblocks(true, good0);
3632}
3633
3634// Tests blocking then unblocking policy-forced extensions after the service has
3635// been initialized.
3636TEST_F(ExtensionServiceTest, BlockAndUnblockPolicyExtension) {
3637 InitializeEmptyExtensionServiceWithTestingPrefs();
3638
3639 {
3640 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3641 // // Blacklist everything.
3642 // pref.SetBlacklistedByDefault(true);
3643 // Mark good.crx for force-installation.
3644 pref.SetIndividualExtensionAutoInstalled(
3645 good_crx, "http://example.com/update_url", true);
3646 }
3647
3648 // Have policy force-install an extension.
lazyboya00eafc2017-04-08 00:57:193649 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:223650 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
mlerman6a37b6a42014-11-26 22:10:533651 provider->UpdateOrAddExtension(
3652 good_crx, "1.0.0.0", data_dir().AppendASCII("good_crx"));
3653
3654 // Reloading extensions should find our externally registered extension
3655 // and install it.
lazyboy8a08c9d2017-04-11 19:53:223656 WaitForExternalExtensionInstalled();
mlerman6a37b6a42014-11-26 22:10:533657
3658 AssertExtensionBlocksAndUnblocks(false, good_crx);
3659}
3660
3661
3662#if defined(ENABLE_BLACKLIST_TESTS)
3663// Tests blocking then unblocking extensions that are blacklisted both before
3664// and after Init().
3665TEST_F(ExtensionServiceTest, BlockAndUnblockBlacklistedExtension) {
Devlin Cronineea1b7a2018-05-26 02:46:213666 TestBlacklist test_blacklist;
mlerman6a37b6a42014-11-26 22:10:533667
3668 InitializeGoodInstalledExtensionService();
3669 test_blacklist.Attach(service()->blacklist_);
3670
Devlin Cronineea1b7a2018-05-26 02:46:213671 test_blacklist.SetBlacklistState(good0, BLACKLISTED_MALWARE, true);
Gabriel Charette01507a22017-09-27 21:30:083672 content::RunAllTasksUntilIdle();
mlerman6a37b6a42014-11-26 22:10:533673
3674 service()->Init();
3675
Devlin Cronineea1b7a2018-05-26 02:46:213676 test_blacklist.SetBlacklistState(good1, BLACKLISTED_MALWARE, true);
Gabriel Charette01507a22017-09-27 21:30:083677 content::RunAllTasksUntilIdle();
mlerman6a37b6a42014-11-26 22:10:533678
3679 // Blacklisted extensions stay blacklisted.
3680 AssertExtensionBlocksAndUnblocks(false, good0);
3681 AssertExtensionBlocksAndUnblocks(false, good1);
3682
3683 service()->BlockAllExtensions();
3684
3685 // Remove an extension from the blacklist while the service is blocked.
Devlin Cronineea1b7a2018-05-26 02:46:213686 test_blacklist.SetBlacklistState(good0, NOT_BLACKLISTED, true);
mlerman6a37b6a42014-11-26 22:10:533687 // Add an extension to the blacklist while the service is blocked.
Devlin Cronineea1b7a2018-05-26 02:46:213688 test_blacklist.SetBlacklistState(good2, BLACKLISTED_MALWARE, true);
Gabriel Charette01507a22017-09-27 21:30:083689 content::RunAllTasksUntilIdle();
mlerman6a37b6a42014-11-26 22:10:533690
3691 // Go directly to blocked, do not pass go, do not collect $200.
3692 ASSERT_TRUE(IsBlocked(good0));
3693 // Get on the blacklist - even if you were blocked!
3694 ASSERT_FALSE(IsBlocked(good2));
3695}
3696#endif // defined(ENABLE_BLACKLIST_TESTS)
3697
3698// Tests blocking then unblocking enabled component extensions after the service
3699// has been initialized.
3700TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledComponentExtension) {
3701 InitializeEmptyExtensionServiceWithTestingPrefs();
3702
3703 // Install a component extension.
3704 base::FilePath path = data_dir()
3705 .AppendASCII("good")
3706 .AppendASCII("Extensions")
3707 .AppendASCII(good0)
3708 .AppendASCII("1.0.0.0");
3709 std::string manifest;
Devlin Cronineea1b7a2018-05-26 02:46:213710 ASSERT_TRUE(
3711 base::ReadFileToString(path.Append(kManifestFilename), &manifest));
mlerman6a37b6a42014-11-26 22:10:533712 service()->component_loader()->Add(manifest, path);
3713 service()->Init();
3714
3715 // Component extension should never block.
3716 AssertExtensionBlocksAndUnblocks(false, good0);
3717}
3718
3719// Tests blocking then unblocking a theme after the service has been
3720// initialized.
3721TEST_F(ExtensionServiceTest, BlockAndUnblockTheme) {
3722 InitializeEmptyExtensionService();
3723 service()->Init();
3724
3725 base::FilePath path = data_dir().AppendASCII("theme.crx");
3726 InstallCRX(path, INSTALL_NEW);
3727
3728 AssertExtensionBlocksAndUnblocks(true, theme_crx);
3729}
3730
3731// Tests that blocking extensions before Init() results in loading blocked
3732// extensions.
3733TEST_F(ExtensionServiceTest, WillNotLoadExtensionsWhenBlocked) {
3734 InitializeGoodInstalledExtensionService();
3735
3736 service()->BlockAllExtensions();
3737
3738 service()->Init();
3739
3740 ASSERT_TRUE(IsBlocked(good0));
3741 ASSERT_TRUE(IsBlocked(good0));
3742 ASSERT_TRUE(IsBlocked(good0));
3743}
3744
mlerman3690e5be2014-12-01 22:57:443745// Tests that IsEnabledExtension won't crash on an uninstalled extension.
3746TEST_F(ExtensionServiceTest, IsEnabledExtensionBlockedAndNotInstalled) {
3747 InitializeEmptyExtensionService();
3748
3749 service()->BlockAllExtensions();
3750
3751 service()->IsExtensionEnabled(theme_crx);
3752}
3753
[email protected]306a2bd2010-08-11 14:56:363754// Will not install extension blacklisted by policy.
[email protected]d9a61e12012-11-14 02:43:473755TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
binjin1569c9b2014-09-05 13:33:183756 InitializeEmptyExtensionServiceWithTestingPrefs();
[email protected]306a2bd2010-08-11 14:56:363757
[email protected]306a2bd2010-08-11 14:56:363758 // Blacklist everything.
[email protected]43d3bf82011-04-11 07:46:583759 {
binjinb2454382014-09-22 15:17:433760 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3761 pref.SetBlacklistedByDefault(true);
[email protected]43d3bf82011-04-11 07:46:583762 }
[email protected]306a2bd2010-08-11 14:56:363763
3764 // Blacklist prevents us from installing good_crx.
[email protected]f484f8d52014-06-12 08:38:183765 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503766 InstallCRX(path, INSTALL_FAILED);
[email protected]f484f8d52014-06-12 08:38:183767 EXPECT_EQ(0u, registry()->enabled_extensions().size());
[email protected]306a2bd2010-08-11 14:56:363768
3769 // Now whitelist this particular extension.
[email protected]43d3bf82011-04-11 07:46:583770 {
binjinb2454382014-09-22 15:17:433771 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3772 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
[email protected]43d3bf82011-04-11 07:46:583773 }
3774
[email protected]306a2bd2010-08-11 14:56:363775 // Ensure we can now install good_crx.
[email protected]8f512c72011-11-22 21:02:503776 InstallCRX(path, INSTALL_NEW);
[email protected]f484f8d52014-06-12 08:38:183777 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]306a2bd2010-08-11 14:56:363778}
3779
[email protected]aa96d3a2010-08-21 08:45:253780// Extension blacklisted by policy get unloaded after installing.
[email protected]d9a61e12012-11-14 02:43:473781TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
binjinb2454382014-09-22 15:17:433782 InitializeEmptyExtensionServiceWithTestingPrefs();
[email protected]aa96d3a2010-08-21 08:45:253783
3784 // Install good_crx.
[email protected]f484f8d52014-06-12 08:38:183785 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503786 InstallCRX(path, INSTALL_NEW);
[email protected]f484f8d52014-06-12 08:38:183787 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]aa96d3a2010-08-21 08:45:253788
binjinb2454382014-09-22 15:17:433789 {
3790 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
[email protected]acd78969c2010-12-08 09:49:113791 // Blacklist this extension.
binjinb2454382014-09-22 15:17:433792 pref.SetIndividualExtensionInstallationAllowed(good_crx, false);
[email protected]acd78969c2010-12-08 09:49:113793 }
[email protected]aa96d3a2010-08-21 08:45:253794
3795 // Extension should not be running now.
Gabriel Charette01507a22017-09-27 21:30:083796 content::RunAllTasksUntilIdle();
[email protected]f484f8d52014-06-12 08:38:183797 EXPECT_EQ(0u, registry()->enabled_extensions().size());
[email protected]aa96d3a2010-08-21 08:45:253798}
3799
[email protected]05aad2da2011-10-28 10:12:373800// Tests that component extensions are not blacklisted by policy.
[email protected]d9a61e12012-11-14 02:43:473801TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
binjinb2454382014-09-22 15:17:433802 InitializeEmptyExtensionServiceWithTestingPrefs();
[email protected]05aad2da2011-10-28 10:12:373803
3804 // Blacklist everything.
3805 {
binjinb2454382014-09-22 15:17:433806 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3807 pref.SetBlacklistedByDefault(true);
[email protected]05aad2da2011-10-28 10:12:373808 }
3809
3810 // Install a component extension.
[email protected]f484f8d52014-06-12 08:38:183811 base::FilePath path = data_dir()
3812 .AppendASCII("good")
3813 .AppendASCII("Extensions")
3814 .AppendASCII(good0)
3815 .AppendASCII("1.0.0.0");
[email protected]05aad2da2011-10-28 10:12:373816 std::string manifest;
Devlin Cronineea1b7a2018-05-26 02:46:213817 ASSERT_TRUE(
3818 base::ReadFileToString(path.Append(kManifestFilename), &manifest));
[email protected]f484f8d52014-06-12 08:38:183819 service()->component_loader()->Add(manifest, path);
3820 service()->Init();
[email protected]05aad2da2011-10-28 10:12:373821
3822 // Extension should be installed despite blacklist.
[email protected]f484f8d52014-06-12 08:38:183823 ASSERT_EQ(1u, registry()->enabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:263824 EXPECT_TRUE(registry()->GetExtensionById(good0, ExtensionRegistry::ENABLED));
[email protected]05aad2da2011-10-28 10:12:373825
3826 // Poke external providers and make sure the extension is still present.
[email protected]f484f8d52014-06-12 08:38:183827 service()->CheckForExternalUpdates();
3828 ASSERT_EQ(1u, registry()->enabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:263829 EXPECT_TRUE(registry()->GetExtensionById(good0, ExtensionRegistry::ENABLED));
[email protected]05aad2da2011-10-28 10:12:373830
3831 // Extension should not be uninstalled on blacklist changes.
3832 {
binjinb2454382014-09-22 15:17:433833 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3834 pref.SetIndividualExtensionInstallationAllowed(good0, false);
[email protected]05aad2da2011-10-28 10:12:373835 }
Gabriel Charette01507a22017-09-27 21:30:083836 content::RunAllTasksUntilIdle();
[email protected]f484f8d52014-06-12 08:38:183837 ASSERT_EQ(1u, registry()->enabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:263838 EXPECT_TRUE(registry()->GetExtensionById(good0, ExtensionRegistry::ENABLED));
[email protected]05aad2da2011-10-28 10:12:373839}
3840
Nick Peterson0203be4a2017-07-19 00:25:143841// Tests that active permissions are not revoked from component extensions
3842// by policy when the policy is updated. https://crbug.com/746017.
3843TEST_F(ExtensionServiceTest, ComponentExtensionWhitelistedPermission) {
3844 InitializeEmptyExtensionServiceWithTestingPrefs();
3845
3846 // Install a component extension.
3847 base::FilePath path = data_dir()
3848 .AppendASCII("good")
3849 .AppendASCII("Extensions")
3850 .AppendASCII(good0)
3851 .AppendASCII("1.0.0.0");
3852 std::string manifest;
Devlin Cronineea1b7a2018-05-26 02:46:213853 ASSERT_TRUE(
3854 base::ReadFileToString(path.Append(kManifestFilename), &manifest));
Nick Peterson0203be4a2017-07-19 00:25:143855 service()->component_loader()->Add(manifest, path);
3856 service()->Init();
3857
3858 // Extension should have the "tabs" permission.
David Bertoni58c113a2019-08-02 19:53:263859 EXPECT_TRUE(registry()
3860 ->GetExtensionById(good0, ExtensionRegistry::ENABLED)
Nick Peterson0203be4a2017-07-19 00:25:143861 ->permissions_data()
3862 ->active_permissions()
Devlin Cronineea1b7a2018-05-26 02:46:213863 .HasAPIPermission(APIPermission::kTab));
Nick Peterson0203be4a2017-07-19 00:25:143864
3865 // Component should not lose permissions on policy change.
3866 {
3867 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3868 pref.AddBlockedPermission(good0, "tabs");
3869 }
3870
3871 service()->OnExtensionManagementSettingsChanged();
Gabriel Charette01507a22017-09-27 21:30:083872 content::RunAllTasksUntilIdle();
David Bertoni58c113a2019-08-02 19:53:263873 EXPECT_TRUE(registry()
3874 ->GetExtensionById(good0, ExtensionRegistry::ENABLED)
Nick Peterson0203be4a2017-07-19 00:25:143875 ->permissions_data()
3876 ->active_permissions()
Devlin Cronineea1b7a2018-05-26 02:46:213877 .HasAPIPermission(APIPermission::kTab));
Nick Peterson0203be4a2017-07-19 00:25:143878}
3879
[email protected]05aad2da2011-10-28 10:12:373880// Tests that policy-installed extensions are not blacklisted by policy.
[email protected]d9a61e12012-11-14 02:43:473881TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
binjin1569c9b2014-09-05 13:33:183882 InitializeEmptyExtensionServiceWithTestingPrefs();
[email protected]05aad2da2011-10-28 10:12:373883
[email protected]05aad2da2011-10-28 10:12:373884 {
binjinb2454382014-09-22 15:17:433885 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
[email protected]e410b5f2012-12-14 14:02:243886 // Blacklist everything.
binjinb2454382014-09-22 15:17:433887 pref.SetBlacklistedByDefault(true);
[email protected]e410b5f2012-12-14 14:02:243888 // Mark good.crx for force-installation.
binjinb2454382014-09-22 15:17:433889 pref.SetIndividualExtensionAutoInstalled(
3890 good_crx, "http://example.com/update_url", true);
[email protected]05aad2da2011-10-28 10:12:373891 }
3892
3893 // Have policy force-install an extension.
lazyboya00eafc2017-04-08 00:57:193894 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:223895 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
[email protected]f484f8d52014-06-12 08:38:183896 provider->UpdateOrAddExtension(
3897 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
[email protected]05aad2da2011-10-28 10:12:373898
3899 // Reloading extensions should find our externally registered extension
3900 // and install it.
lazyboy8a08c9d2017-04-11 19:53:223901 WaitForExternalExtensionInstalled();
[email protected]05aad2da2011-10-28 10:12:373902
3903 // Extension should be installed despite blacklist.
[email protected]f484f8d52014-06-12 08:38:183904 ASSERT_EQ(1u, registry()->enabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:263905 EXPECT_TRUE(
3906 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]05aad2da2011-10-28 10:12:373907
3908 // Blacklist update should not uninstall the extension.
3909 {
binjinb2454382014-09-22 15:17:433910 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3911 pref.SetIndividualExtensionInstallationAllowed(good0, false);
[email protected]05aad2da2011-10-28 10:12:373912 }
Gabriel Charette01507a22017-09-27 21:30:083913 content::RunAllTasksUntilIdle();
[email protected]f484f8d52014-06-12 08:38:183914 ASSERT_EQ(1u, registry()->enabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:263915 EXPECT_TRUE(
3916 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]05aad2da2011-10-28 10:12:373917}
3918
[email protected]65187152012-06-02 13:14:143919// Tests that extensions cannot be installed if the policy provider prohibits
3920// it. This functionality is implemented in CrxInstaller::ConfirmInstall().
[email protected]d9a61e12012-11-14 02:43:473921TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
[email protected]65187152012-06-02 13:14:143922 InitializeEmptyExtensionService();
3923
[email protected]f484f8d52014-06-12 08:38:183924 GetManagementPolicy()->UnregisterAllProviders();
Devlin Cronineea1b7a2018-05-26 02:46:213925 TestManagementPolicyProvider provider_(
3926 TestManagementPolicyProvider::PROHIBIT_LOAD);
[email protected]f484f8d52014-06-12 08:38:183927 GetManagementPolicy()->RegisterProvider(&provider_);
[email protected]65187152012-06-02 13:14:143928
[email protected]f484f8d52014-06-12 08:38:183929 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_FAILED);
3930 EXPECT_EQ(0u, registry()->enabled_extensions().size());
[email protected]65187152012-06-02 13:14:143931}
3932
3933// Tests that extensions cannot be loaded from prefs if the policy provider
3934// prohibits it. This functionality is implemented in InstalledLoader::Load().
[email protected]d9a61e12012-11-14 02:43:473935TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
[email protected]65187152012-06-02 13:14:143936 InitializeEmptyExtensionService();
3937
3938 // Create a fake extension to be loaded as though it were read from prefs.
[email protected]f484f8d52014-06-12 08:38:183939 base::FilePath path =
3940 data_dir().AppendASCII("management").AppendASCII("simple_extension");
[email protected]023b3d12013-12-23 18:46:493941 base::DictionaryValue manifest;
[email protected]65187152012-06-02 13:14:143942 manifest.SetString(keys::kName, "simple_extension");
3943 manifest.SetString(keys::kVersion, "1");
Devlin Cronin077ce1f2018-04-25 21:18:553944 manifest.SetInteger(keys::kManifestVersion, 2);
[email protected]12075d12013-02-27 05:38:053945 // UNPACKED is for extensions loaded from a directory. We use it here, even
[email protected]65187152012-06-02 13:14:143946 // though we're testing loading from prefs, so that we don't need to provide
3947 // an extension key.
Devlin Cronineea1b7a2018-05-26 02:46:213948 ExtensionInfo extension_info(&manifest, std::string(), path,
3949 Manifest::UNPACKED);
[email protected]65187152012-06-02 13:14:143950
3951 // Ensure we can load it with no management policy in place.
[email protected]f484f8d52014-06-12 08:38:183952 GetManagementPolicy()->UnregisterAllProviders();
3953 EXPECT_EQ(0u, registry()->enabled_extensions().size());
Devlin Cronineea1b7a2018-05-26 02:46:213954 InstalledLoader(service()).Load(extension_info, false);
[email protected]f484f8d52014-06-12 08:38:183955 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]65187152012-06-02 13:14:143956
[email protected]f484f8d52014-06-12 08:38:183957 const Extension* extension =
3958 (registry()->enabled_extensions().begin())->get();
Devlin Cronineea1b7a2018-05-26 02:46:213959 EXPECT_TRUE(service()->UninstallExtension(
3960 extension->id(), UNINSTALL_REASON_FOR_TESTING, NULL));
[email protected]f484f8d52014-06-12 08:38:183961 EXPECT_EQ(0u, registry()->enabled_extensions().size());
[email protected]65187152012-06-02 13:14:143962
3963 // Ensure we cannot load it if management policy prohibits installation.
Devlin Cronineea1b7a2018-05-26 02:46:213964 TestManagementPolicyProvider provider_(
3965 TestManagementPolicyProvider::PROHIBIT_LOAD);
[email protected]f484f8d52014-06-12 08:38:183966 GetManagementPolicy()->RegisterProvider(&provider_);
[email protected]65187152012-06-02 13:14:143967
Devlin Cronineea1b7a2018-05-26 02:46:213968 InstalledLoader(service()).Load(extension_info, false);
[email protected]f484f8d52014-06-12 08:38:183969 EXPECT_EQ(0u, registry()->enabled_extensions().size());
[email protected]65187152012-06-02 13:14:143970}
3971
3972// Tests disabling an extension when prohibited by the ManagementPolicy.
[email protected]d9a61e12012-11-14 02:43:473973TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
[email protected]65187152012-06-02 13:14:143974 InitializeEmptyExtensionService();
3975
[email protected]f484f8d52014-06-12 08:38:183976 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3977 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3978 EXPECT_EQ(0u, registry()->disabled_extensions().size());
[email protected]65187152012-06-02 13:14:143979
[email protected]f484f8d52014-06-12 08:38:183980 GetManagementPolicy()->UnregisterAllProviders();
Devlin Cronineea1b7a2018-05-26 02:46:213981 TestManagementPolicyProvider provider(
3982 TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
[email protected]f484f8d52014-06-12 08:38:183983 GetManagementPolicy()->RegisterProvider(&provider);
[email protected]65187152012-06-02 13:14:143984
3985 // Attempt to disable it.
Devlin Cronineea1b7a2018-05-26 02:46:213986 service()->DisableExtension(good_crx, disable_reason::DISABLE_USER_ACTION);
[email protected]65187152012-06-02 13:14:143987
[email protected]f484f8d52014-06-12 08:38:183988 EXPECT_EQ(1u, registry()->enabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:263989 EXPECT_TRUE(
3990 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]f484f8d52014-06-12 08:38:183991 EXPECT_EQ(0u, registry()->disabled_extensions().size());
Devlin Cronineea1b7a2018-05-26 02:46:213992 EXPECT_EQ(disable_reason::DISABLE_NONE,
Michael Giuffridab16cab32017-10-04 21:56:093993 ExtensionPrefs::Get(profile())->GetDisableReasons(good_crx));
3994
3995 // Internal disable reasons are allowed.
3996 service()->DisableExtension(
Devlin Cronineea1b7a2018-05-26 02:46:213997 good_crx,
3998 disable_reason::DISABLE_CORRUPTED | disable_reason::DISABLE_USER_ACTION);
Michael Giuffridab16cab32017-10-04 21:56:093999
4000 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4001 EXPECT_EQ(1u, registry()->disabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:264002 EXPECT_TRUE(
4003 registry()->GetExtensionById(good_crx, ExtensionRegistry::COMPATIBILITY));
4004 EXPECT_FALSE(
4005 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
Devlin Cronineea1b7a2018-05-26 02:46:214006 EXPECT_EQ(disable_reason::DISABLE_CORRUPTED,
Michael Giuffridab16cab32017-10-04 21:56:094007 ExtensionPrefs::Get(profile())->GetDisableReasons(good_crx));
[email protected]65187152012-06-02 13:14:144008}
4009
4010// Tests uninstalling an extension when prohibited by the ManagementPolicy.
[email protected]d9a61e12012-11-14 02:43:474011TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
[email protected]65187152012-06-02 13:14:144012 InitializeEmptyExtensionService();
4013
[email protected]f484f8d52014-06-12 08:38:184014 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4015 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4016 EXPECT_EQ(0u, registry()->disabled_extensions().size());
[email protected]65187152012-06-02 13:14:144017
[email protected]f484f8d52014-06-12 08:38:184018 GetManagementPolicy()->UnregisterAllProviders();
Devlin Cronineea1b7a2018-05-26 02:46:214019 TestManagementPolicyProvider provider(
4020 TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
[email protected]f484f8d52014-06-12 08:38:184021 GetManagementPolicy()->RegisterProvider(&provider);
[email protected]65187152012-06-02 13:14:144022
4023 // Attempt to uninstall it.
Devlin Cronineea1b7a2018-05-26 02:46:214024 EXPECT_FALSE(service()->UninstallExtension(
4025 good_crx, UNINSTALL_REASON_FOR_TESTING, NULL));
[email protected]65187152012-06-02 13:14:144026
[email protected]f484f8d52014-06-12 08:38:184027 EXPECT_EQ(1u, registry()->enabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:264028 EXPECT_TRUE(
4029 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]65187152012-06-02 13:14:144030}
4031
4032// Tests that previously installed extensions that are now prohibited from
Karan Bhatia2a117232017-08-23 00:24:564033// being installed are disabled.
[email protected]d9a61e12012-11-14 02:43:474034TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
[email protected]65187152012-06-02 13:14:144035 InitializeEmptyExtensionService();
4036
[email protected]f484f8d52014-06-12 08:38:184037 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4038 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
4039 EXPECT_EQ(2u, registry()->enabled_extensions().size());
4040 EXPECT_EQ(0u, registry()->disabled_extensions().size());
[email protected]65187152012-06-02 13:14:144041
[email protected]f484f8d52014-06-12 08:38:184042 GetManagementPolicy()->UnregisterAllProviders();
Devlin Cronineea1b7a2018-05-26 02:46:214043 TestManagementPolicyProvider provider(
4044 TestManagementPolicyProvider::PROHIBIT_LOAD);
[email protected]f484f8d52014-06-12 08:38:184045 GetManagementPolicy()->RegisterProvider(&provider);
[email protected]65187152012-06-02 13:14:144046
Karan Bhatia2a117232017-08-23 00:24:564047 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4048
[email protected]65187152012-06-02 13:14:144049 // Run the policy check.
[email protected]f484f8d52014-06-12 08:38:184050 service()->CheckManagementPolicy();
4051 EXPECT_EQ(0u, registry()->enabled_extensions().size());
Karan Bhatia2a117232017-08-23 00:24:564052 EXPECT_EQ(2u, registry()->disabled_extensions().size());
Devlin Cronineea1b7a2018-05-26 02:46:214053 EXPECT_EQ(disable_reason::DISABLE_BLOCKED_BY_POLICY,
Karan Bhatia2a117232017-08-23 00:24:564054 prefs->GetDisableReasons(good_crx));
Devlin Cronineea1b7a2018-05-26 02:46:214055 EXPECT_EQ(disable_reason::DISABLE_BLOCKED_BY_POLICY,
Karan Bhatia2a117232017-08-23 00:24:564056 prefs->GetDisableReasons(page_action));
4057
4058 // Removing the extensions from policy blacklist should re-enable them.
4059 GetManagementPolicy()->UnregisterAllProviders();
4060 service()->CheckManagementPolicy();
4061 EXPECT_EQ(2u, registry()->enabled_extensions().size());
[email protected]f484f8d52014-06-12 08:38:184062 EXPECT_EQ(0u, registry()->disabled_extensions().size());
[email protected]65187152012-06-02 13:14:144063}
4064
4065// Tests that previously disabled extensions that are now required to be
4066// enabled are re-enabled on reinstall.
[email protected]d9a61e12012-11-14 02:43:474067TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
[email protected]65187152012-06-02 13:14:144068 InitializeEmptyExtensionService();
4069
4070 // Install, then disable, an extension.
[email protected]f484f8d52014-06-12 08:38:184071 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4072 EXPECT_EQ(1u, registry()->enabled_extensions().size());
Devlin Cronineea1b7a2018-05-26 02:46:214073 service()->DisableExtension(good_crx, disable_reason::DISABLE_USER_ACTION);
[email protected]f484f8d52014-06-12 08:38:184074 EXPECT_EQ(1u, registry()->disabled_extensions().size());
[email protected]65187152012-06-02 13:14:144075
binjin47947f842014-11-18 12:10:244076 // Register an ExtensionManagementPolicy that requires the extension to remain
[email protected]65187152012-06-02 13:14:144077 // enabled.
[email protected]f484f8d52014-06-12 08:38:184078 GetManagementPolicy()->UnregisterAllProviders();
Devlin Cronineea1b7a2018-05-26 02:46:214079 TestManagementPolicyProvider provider(
4080 TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
[email protected]f484f8d52014-06-12 08:38:184081 GetManagementPolicy()->RegisterProvider(&provider);
[email protected]65187152012-06-02 13:14:144082
4083 // Reinstall the extension.
[email protected]f484f8d52014-06-12 08:38:184084 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_UPDATED);
4085 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4086 EXPECT_EQ(0u, registry()->disabled_extensions().size());
[email protected]65187152012-06-02 13:14:144087}
4088
binjin47947f842014-11-18 12:10:244089// Tests that extensions disabled by management policy can be installed but
4090// will get disabled after installing.
4091TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsEnableOnInstalled) {
4092 InitializeEmptyExtensionService();
4093
4094 // Register an ExtensionManagementPolicy that disables all extensions, with
Minh X. Nguyen45479012017-08-18 21:35:364095 // a specified disable_reason::DisableReason.
binjin47947f842014-11-18 12:10:244096 GetManagementPolicy()->UnregisterAllProviders();
Devlin Cronineea1b7a2018-05-26 02:46:214097 TestManagementPolicyProvider provider(
4098 TestManagementPolicyProvider::MUST_REMAIN_DISABLED);
4099 provider.SetDisableReason(disable_reason::DISABLE_NOT_VERIFIED);
binjin47947f842014-11-18 12:10:244100 GetManagementPolicy()->RegisterProvider(&provider);
4101
4102 // Attempts to install an extensions, it should be installed but disabled.
4103 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4104 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4105 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_WITHOUT_LOAD);
4106 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4107 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4108
4109 // Verifies that the disable reason is set properly.
Devlin Cronineea1b7a2018-05-26 02:46:214110 EXPECT_EQ(disable_reason::DISABLE_NOT_VERIFIED,
binjin47947f842014-11-18 12:10:244111 service()->extension_prefs_->GetDisableReasons(kGoodId));
4112}
4113
binjine6b58b52014-10-31 01:55:574114// Tests that extensions with conflicting required permissions by enterprise
4115// policy cannot be installed.
4116TEST_F(ExtensionServiceTest, PolicyBlockedPermissionNewExtensionInstall) {
4117 InitializeEmptyExtensionServiceWithTestingPrefs();
4118 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4119
4120 {
4121 // Update policy to block one of the required permissions of target.
4122 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4123 pref.AddBlockedPermission("*", "tabs");
4124 }
4125
4126 // The extension should be failed to install.
4127 PackAndInstallCRX(path, INSTALL_FAILED);
4128
4129 {
4130 // Update policy to block one of the optional permissions instead.
4131 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4132 pref.ClearBlockedPermissions("*");
4133 pref.AddBlockedPermission("*", "history");
4134 }
4135
4136 // The extension should succeed to install this time.
4137 std::string id = PackAndInstallCRX(path, INSTALL_NEW)->id();
4138
4139 // Uninstall the extension and update policy to block some arbitrary
4140 // unknown permission.
Devlin Cronin6fd1cd62017-12-05 19:13:574141 UninstallExtension(id);
binjine6b58b52014-10-31 01:55:574142 {
4143 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4144 pref.ClearBlockedPermissions("*");
4145 pref.AddBlockedPermission("*", "unknown.permission.for.testing");
4146 }
4147
4148 // The extension should succeed to install as well.
4149 PackAndInstallCRX(path, INSTALL_NEW);
4150}
4151
4152// Tests that extension supposed to be force installed but with conflicting
4153// required permissions cannot be installed.
4154TEST_F(ExtensionServiceTest, PolicyBlockedPermissionConflictsWithForceInstall) {
4155 InitializeEmptyExtensionServiceWithTestingPrefs();
4156
4157 // Pack the crx file.
4158 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4159 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4160 base::ScopedTempDir temp_dir;
4161 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:224162 base::FilePath crx_path = temp_dir.GetPath().AppendASCII("temp.crx");
binjine6b58b52014-10-31 01:55:574163
4164 PackCRX(path, pem_path, crx_path);
4165
4166 {
4167 // Block one of the required permissions.
4168 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4169 pref.AddBlockedPermission("*", "tabs");
4170 }
4171
lazyboya00eafc2017-04-08 00:57:194172 // Use MockExternalProvider to simulate force installing extension.
4173 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:224174 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
binjine6b58b52014-10-31 01:55:574175 provider->UpdateOrAddExtension(permissions_blocklist, "1.0", crx_path);
4176
lazyboy8a08c9d2017-04-11 19:53:224177 // Attempts to force install this extension.
4178 WaitForExternalExtensionInstalled();
binjine6b58b52014-10-31 01:55:574179
4180 // The extension should not be installed.
4181 ASSERT_FALSE(service()->GetInstalledExtension(permissions_blocklist));
4182
4183 // Remove this extension from pending extension manager as we would like to
4184 // give another attempt later.
4185 service()->pending_extension_manager()->Remove(permissions_blocklist);
4186
4187 {
4188 // Clears the permission block list.
4189 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4190 pref.ClearBlockedPermissions("*");
4191 }
4192
lazyboy8a08c9d2017-04-11 19:53:224193 // Attempts to force install this extension again.
4194 WaitForExternalExtensionInstalled();
binjine6b58b52014-10-31 01:55:574195
4196 const Extension* installed =
4197 service()->GetInstalledExtension(permissions_blocklist);
4198 ASSERT_TRUE(installed);
4199 EXPECT_EQ(installed->location(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4200}
4201
4202// Tests that newer versions of an extension with conflicting required
4203// permissions by enterprise policy cannot be updated to.
4204TEST_F(ExtensionServiceTest, PolicyBlockedPermissionExtensionUpdate) {
4205 InitializeEmptyExtensionServiceWithTestingPrefs();
4206
4207 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4208 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4209 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4210
4211 // Install 'permissions_blocklist'.
4212 const Extension* installed = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
4213 EXPECT_EQ(installed->id(), permissions_blocklist);
4214
4215 {
4216 // Block one of the required permissions of 'permissions_blocklist2'.
4217 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4218 pref.AddBlockedPermission("*", "downloads");
4219 }
4220
4221 // Install 'permissions_blocklist' again, should be updated.
4222 const Extension* updated = PackAndInstallCRX(path, pem_path, INSTALL_UPDATED);
4223 EXPECT_EQ(updated->id(), permissions_blocklist);
4224
4225 std::string old_version = updated->VersionString();
4226
4227 // Attempts to update to 'permissions_blocklist2' should fail.
4228 PackAndInstallCRX(path2, pem_path, INSTALL_FAILED);
4229
4230 // Verify that the old version is still enabled.
David Bertoni58c113a2019-08-02 19:53:264231 updated = registry()->GetExtensionById(permissions_blocklist,
4232 ExtensionRegistry::ENABLED);
binjine6b58b52014-10-31 01:55:574233 ASSERT_TRUE(updated);
4234 EXPECT_EQ(old_version, updated->VersionString());
4235}
4236
4237// Tests that policy update with additional permissions blocked revoke
4238// conflicting granted optional permissions and unload extensions with
4239// conflicting required permissions, including the force installed ones.
4240TEST_F(ExtensionServiceTest, PolicyBlockedPermissionPolicyUpdate) {
4241 InitializeEmptyExtensionServiceWithTestingPrefs();
4242
4243 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4244 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4245 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4246
4247 // Pack the crx file.
4248 base::ScopedTempDir temp_dir;
4249 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:224250 base::FilePath crx_path = temp_dir.GetPath().AppendASCII("temp.crx");
binjine6b58b52014-10-31 01:55:574251
4252 PackCRX(path2, pem_path, crx_path);
4253
4254 // Install two arbitary extensions with specified manifest.
4255 std::string ext1 = PackAndInstallCRX(path, INSTALL_NEW)->id();
4256 std::string ext2 = PackAndInstallCRX(path2, INSTALL_NEW)->id();
4257 ASSERT_NE(ext1, permissions_blocklist);
4258 ASSERT_NE(ext2, permissions_blocklist);
4259 ASSERT_NE(ext1, ext2);
4260
4261 // Force install another extension with known id and same manifest as 'ext2'.
4262 std::string ext2_forced = permissions_blocklist;
lazyboya00eafc2017-04-08 00:57:194263 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:224264 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
binjine6b58b52014-10-31 01:55:574265 provider->UpdateOrAddExtension(ext2_forced, "2.0", crx_path);
lazyboy8a08c9d2017-04-11 19:53:224266 WaitForExternalExtensionInstalled();
binjine6b58b52014-10-31 01:55:574267
Devlin Cronineea1b7a2018-05-26 02:46:214268 ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
binjine6b58b52014-10-31 01:55:574269
4270 // Verify all three extensions are installed and enabled.
4271 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext1));
4272 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2));
4273 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2_forced));
4274
4275 // Grant all optional permissions to each extension.
4276 GrantAllOptionalPermissions(ext1);
4277 GrantAllOptionalPermissions(ext2);
4278 GrantAllOptionalPermissions(ext2_forced);
4279
dchengc963c7142016-04-08 03:55:224280 std::unique_ptr<const PermissionSet> active_permissions =
rdevlin.cronine2d0fd02015-09-24 22:35:494281 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
Devlin Cronineea1b7a2018-05-26 02:46:214282 EXPECT_TRUE(active_permissions->HasAPIPermission(APIPermission::kDownloads));
binjine6b58b52014-10-31 01:55:574283
4284 // Set policy to block 'downloads' permission.
4285 {
4286 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4287 pref.AddBlockedPermission("*", "downloads");
4288 }
4289
Gabriel Charette01507a22017-09-27 21:30:084290 content::RunAllTasksUntilIdle();
binjine6b58b52014-10-31 01:55:574291
4292 // 'ext1' should still be enabled, but with 'downloads' permission revoked.
4293 EXPECT_TRUE(registry->enabled_extensions().GetByID(ext1));
4294 active_permissions =
4295 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
Devlin Cronineea1b7a2018-05-26 02:46:214296 EXPECT_FALSE(active_permissions->HasAPIPermission(APIPermission::kDownloads));
binjine6b58b52014-10-31 01:55:574297
4298 // 'ext2' should be disabled because one of its required permissions is
4299 // blocked.
4300 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2));
4301
4302 // 'ext2_forced' should be handled the same as 'ext2'
4303 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2_forced));
4304}
4305
[email protected]ebc3aec2013-10-22 02:39:174306// Flaky on windows; http://crbug.com/309833
4307#if defined(OS_WIN)
4308#define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
4309#else
4310#define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
4311#endif
[email protected]893642c2014-02-03 06:53:134312TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) {
[email protected]a39921b42012-02-28 03:42:544313 InitializeEmptyExtensionService();
[email protected]a39921b42012-02-28 03:42:544314
4315 {
4316 // Register and install an external extension.
lazyboya00eafc2017-04-08 00:57:194317 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:224318 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]f484f8d52014-06-12 08:38:184319 provider->UpdateOrAddExtension(
4320 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
[email protected]a39921b42012-02-28 03:42:544321 }
4322 {
4323 // Have policy force-install an extension.
lazyboya00eafc2017-04-08 00:57:194324 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:224325 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
[email protected]f484f8d52014-06-12 08:38:184326 provider->UpdateOrAddExtension(
4327 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
[email protected]a39921b42012-02-28 03:42:544328 }
4329
4330 // Providers are set up. Let them run.
[email protected]97d6a5c2013-11-11 23:51:244331 int count = 2;
4332 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:214333 NOTIFICATION_CRX_INSTALLER_DONE,
[email protected]97d6a5c2013-11-11 23:51:244334 base::Bind(&WaitForCountNotificationsCallback, &count));
[email protected]f484f8d52014-06-12 08:38:184335 service()->CheckForExternalUpdates();
[email protected]6d057a0c2013-07-09 21:12:074336
[email protected]97d6a5c2013-11-11 23:51:244337 observer.Wait();
[email protected]a39921b42012-02-28 03:42:544338
[email protected]f484f8d52014-06-12 08:38:184339 ASSERT_EQ(2u, registry()->enabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:264340 EXPECT_TRUE(
4341 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
4342 EXPECT_TRUE(
4343 registry()->GetExtensionById(page_action, ExtensionRegistry::ENABLED));
[email protected]f484f8d52014-06-12 08:38:184344 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
[email protected]a39921b42012-02-28 03:42:544345 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
4346 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
4347}
4348
rdevlin.cronine1456712016-12-29 22:47:284349// Tests that an extension added through an external source is initially
4350// disabled with the "prompt for external extensions" feature.
4351TEST_F(ExtensionServiceTest, ExternalExtensionDisabledOnInstallation) {
4352 FeatureSwitch::ScopedOverride external_prompt_override(
4353 FeatureSwitch::prompt_for_external_extensions(), true);
4354 InitializeEmptyExtensionService();
4355
4356 // Register and install an external extension.
lazyboya00eafc2017-04-08 00:57:194357 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:224358 AddMockExternalProvider(Manifest::EXTERNAL_PREF); // Takes ownership.
rdevlin.cronine1456712016-12-29 22:47:284359 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
4360 data_dir().AppendASCII("good.crx"));
4361
4362 WaitForExternalExtensionInstalled();
4363
4364 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
4365 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4366 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
Devlin Cronineea1b7a2018-05-26 02:46:214367 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
rdevlin.cronine1456712016-12-29 22:47:284368 prefs->GetDisableReasons(good_crx));
4369
4370 // Updating the extension shouldn't cause it to be enabled.
4371 provider->UpdateOrAddExtension(good_crx, "1.0.0.1",
4372 data_dir().AppendASCII("good2.crx"));
4373 WaitForExternalExtensionInstalled();
4374
4375 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
4376 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
Devlin Cronineea1b7a2018-05-26 02:46:214377 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
rdevlin.cronine1456712016-12-29 22:47:284378 prefs->GetDisableReasons(good_crx));
4379 const Extension* extension =
4380 registry()->disabled_extensions().GetByID(good_crx);
4381 ASSERT_TRUE(extension);
4382 // Double check that we did, in fact, update the extension.
Devlin Cronin03bf2d22017-12-20 08:21:054383 EXPECT_EQ("1.0.0.1", extension->version().GetString());
rdevlin.cronine1456712016-12-29 22:47:284384}
4385
4386// Test that if an extension is installed before the "prompt for external
4387// extensions" feature is enabled, but is updated when the feature is
4388// enabled, the extension is not disabled.
4389TEST_F(ExtensionServiceTest, ExternalExtensionIsNotDisabledOnUpdate) {
4390 auto external_prompt_override =
Jinho Bangb5216cec2018-01-17 19:43:114391 std::make_unique<FeatureSwitch::ScopedOverride>(
rdevlin.cronine1456712016-12-29 22:47:284392 FeatureSwitch::prompt_for_external_extensions(), false);
4393 InitializeEmptyExtensionService();
4394
4395 // Register and install an external extension.
lazyboya00eafc2017-04-08 00:57:194396 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:224397 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
rdevlin.cronine1456712016-12-29 22:47:284398 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
4399 data_dir().AppendASCII("good.crx"));
4400
4401 WaitForExternalExtensionInstalled();
4402
4403 EXPECT_TRUE(registry()->enabled_extensions().Contains(good_crx));
4404 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4405 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
Devlin Cronineea1b7a2018-05-26 02:46:214406 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
rdevlin.cronine1456712016-12-29 22:47:284407
4408 provider->UpdateOrAddExtension(good_crx, "1.0.0.1",
4409 data_dir().AppendASCII("good2.crx"));
4410
4411 // We explicitly reset the override first. ScopedOverrides reset the value
4412 // to the original value on destruction, but if we reset by passing a new
4413 // object, the new object is constructed (overriding the current value)
4414 // before the old is destructed (which will immediately reset to the
4415 // original).
4416 external_prompt_override.reset();
Jinho Bangb5216cec2018-01-17 19:43:114417 external_prompt_override = std::make_unique<FeatureSwitch::ScopedOverride>(
rdevlin.cronine1456712016-12-29 22:47:284418 FeatureSwitch::prompt_for_external_extensions(), true);
4419 WaitForExternalExtensionInstalled();
4420
4421 EXPECT_TRUE(registry()->enabled_extensions().Contains(good_crx));
4422 {
4423 const Extension* extension =
4424 registry()->enabled_extensions().GetByID(good_crx);
4425 ASSERT_TRUE(extension);
Devlin Cronin03bf2d22017-12-20 08:21:054426 EXPECT_EQ("1.0.0.1", extension->version().GetString());
rdevlin.cronine1456712016-12-29 22:47:284427 }
4428 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
Devlin Cronineea1b7a2018-05-26 02:46:214429 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
rdevlin.cronine1456712016-12-29 22:47:284430}
4431
Devlin Cronin63bd5552018-01-18 19:05:354432// Test that if an external extension warning is ignored three times, the
4433// extension no longer prompts
4434TEST_F(ExtensionServiceTest, ExternalExtensionRemainsDisabledIfIgnored) {
4435 FeatureSwitch::ScopedOverride prompt_override(
4436 FeatureSwitch::prompt_for_external_extensions(), true);
4437 InitializeEmptyExtensionService();
4438
4439 // Register and install an external extension.
4440 MockExternalProvider* provider =
4441 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
4442 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
4443 data_dir().AppendASCII("good.crx"));
4444
4445 WaitForExternalExtensionInstalled();
4446
4447 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
4448 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4449 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
Devlin Cronineea1b7a2018-05-26 02:46:214450 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
Devlin Cronin63bd5552018-01-18 19:05:354451 prefs->GetDisableReasons(good_crx));
4452
Devlin Cronineea1b7a2018-05-26 02:46:214453 ExternalInstallManager* external_install_manager =
Devlin Cronin63bd5552018-01-18 19:05:354454 service()->external_install_manager();
4455
4456 for (int i = 0; i < 3; ++i) {
4457 std::vector<ExternalInstallError*> errors =
4458 external_install_manager->GetErrorsForTesting();
4459 ASSERT_EQ(1u, errors.size());
4460 errors[0]->OnInstallPromptDone(ExtensionInstallPrompt::Result::ABORTED);
4461 base::RunLoop().RunUntilIdle();
4462 // Note: Calling OnInstallPromptDone() can result in the removal of the
4463 // error by the manager (which owns the object), so the contents |errors|
4464 // are invalidated now!
4465 EXPECT_TRUE(external_install_manager->GetErrorsForTesting().empty());
4466 external_install_manager->ClearShownIdsForTesting();
4467 external_install_manager->UpdateExternalExtensionAlert();
4468 }
4469
4470 // We should have stopped prompting, since the user was shown the warning
4471 // three times.
4472 EXPECT_TRUE(external_install_manager->GetErrorsForTesting().empty());
4473 EXPECT_TRUE(prefs->IsExternalExtensionAcknowledged(good_crx));
4474 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
Devlin Cronineea1b7a2018-05-26 02:46:214475 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
Devlin Cronin63bd5552018-01-18 19:05:354476 prefs->GetDisableReasons(good_crx));
4477
4478 // The extension should remain disabled.
4479 service()->ReloadExtensionsForTest();
4480 EXPECT_TRUE(prefs->IsExternalExtensionAcknowledged(good_crx));
4481 EXPECT_TRUE(registry()->disabled_extensions().Contains(good_crx));
Devlin Cronineea1b7a2018-05-26 02:46:214482 EXPECT_EQ(disable_reason::DISABLE_EXTERNAL_EXTENSION,
Devlin Cronin63bd5552018-01-18 19:05:354483 prefs->GetDisableReasons(good_crx));
Devlin Cronin96a2cf92018-04-18 19:09:594484
4485 // Then re-enabling the extension (or otherwise causing the alert to be
4486 // updated again) should work. Regression test for https://crbug.com/736292.
4487 {
Devlin Cronineea1b7a2018-05-26 02:46:214488 TestExtensionRegistryObserver registry_observer(registry());
Devlin Cronin96a2cf92018-04-18 19:09:594489 service()->EnableExtension(good_crx);
4490 registry_observer.WaitForExtensionLoaded();
4491 base::RunLoop().RunUntilIdle();
4492 }
Devlin Cronin63bd5552018-01-18 19:05:354493}
4494
[email protected]a7cd28e2012-10-05 21:03:364495#if !defined(OS_CHROMEOS)
4496// This tests if default apps are installed correctly.
[email protected]d9a61e12012-11-14 02:43:474497TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
[email protected]a7cd28e2012-10-05 21:03:364498 InitializeEmptyExtensionService();
[email protected]a7cd28e2012-10-05 21:03:364499
4500 {
4501 std::string json_data =
4502 "{"
4503 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
4504 " \"external_crx\": \"good.crx\","
4505 " \"external_version\": \"1.0.0.0\","
4506 " \"is_bookmark_app\": false"
4507 " }"
4508 "}";
[email protected]f484f8d52014-06-12 08:38:184509 default_apps::Provider* provider = new default_apps::Provider(
Devlin Cronineea1b7a2018-05-26 02:46:214510 profile(), service(), new ExternalTestingLoader(json_data, data_dir()),
4511 Manifest::INTERNAL, Manifest::INVALID_LOCATION,
[email protected]f484f8d52014-06-12 08:38:184512 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
[email protected]a7cd28e2012-10-05 21:03:364513
lazyboy8a08c9d2017-04-11 19:53:224514 service()->AddProviderForTesting(base::WrapUnique(provider));
[email protected]a7cd28e2012-10-05 21:03:364515 }
4516
[email protected]f484f8d52014-06-12 08:38:184517 ASSERT_EQ(0u, registry()->enabled_extensions().size());
lazyboy8a08c9d2017-04-11 19:53:224518 WaitForExternalExtensionInstalled();
[email protected]a7cd28e2012-10-05 21:03:364519
[email protected]f484f8d52014-06-12 08:38:184520 ASSERT_EQ(1u, registry()->enabled_extensions().size());
David Bertoni58c113a2019-08-02 19:53:264521 EXPECT_TRUE(
4522 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
4523 const Extension* extension =
4524 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED);
[email protected]a7cd28e2012-10-05 21:03:364525 EXPECT_TRUE(extension->from_webstore());
4526 EXPECT_TRUE(extension->was_installed_by_default());
[email protected]a7cd28e2012-10-05 21:03:364527}
4528#endif
4529
timlohac695622017-04-03 07:52:584530// Crashes on Linux/CrOS. https://crbug.com/703712
4531#if defined(OS_LINUX) || defined(OS_CHROMEOS)
4532#define MAYBE_UpdatingPendingExternalExtensionWithFlags \
4533 DISABLED_UpdatingPendingExternalExtensionWithFlags
4534#else
4535#define MAYBE_UpdatingPendingExternalExtensionWithFlags \
4536 UpdatingPendingExternalExtensionWithFlags
4537#endif
4538
4539TEST_F(ExtensionServiceTest, MAYBE_UpdatingPendingExternalExtensionWithFlags) {
mamir0128d5a2016-07-15 20:55:484540 // Regression test for crbug.com/627522
4541 const char kPrefFromBookmark[] = "from_bookmark";
4542
4543 InitializeEmptyExtensionService();
4544
4545 base::FilePath path = data_dir().AppendASCII("good.crx");
mamir0128d5a2016-07-15 20:55:484546
4547 // Register and install an external extension.
Devlin Cronind4c2a8f32017-09-29 17:08:304548 base::Version version("1.0.0.0");
mamir0128d5a2016-07-15 20:55:484549 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:214550 NOTIFICATION_CRX_INSTALLER_DONE,
mamir0128d5a2016-07-15 20:55:484551 content::NotificationService::AllSources());
Devlin Cronin92c52cac2017-10-02 21:29:014552 ExternalInstallInfoFile info(good_crx, version, path, Manifest::EXTERNAL_PREF,
4553 Extension::FROM_BOOKMARK,
4554 false /* mark_acknowledged */,
4555 false /* install_immediately */);
4556 ASSERT_TRUE(service()->OnExternalExtensionFileFound(info));
mamir0128d5a2016-07-15 20:55:484557 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
4558
4559 // Upgrade to version 2.0, the flag should be preserved.
4560 path = data_dir().AppendASCII("good2.crx");
4561 UpdateExtension(good_crx, path, ENABLED);
4562 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
David Bertoni58c113a2019-08-02 19:53:264563 const Extension* extension =
4564 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED);
mamir0128d5a2016-07-15 20:55:484565 ASSERT_TRUE(extension);
4566 ASSERT_TRUE(extension->from_bookmark());
4567}
4568
[email protected]cd500f72010-06-25 23:44:324569// Tests disabling extensions
[email protected]d9a61e12012-11-14 02:43:474570TEST_F(ExtensionServiceTest, DisableExtension) {
[email protected]eaa7dd182010-12-14 11:09:004571 InitializeEmptyExtensionService();
[email protected]cd500f72010-06-25 23:44:324572
[email protected]f484f8d52014-06-12 08:38:184573 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
David Bertoni58c113a2019-08-02 19:53:264574 EXPECT_TRUE(
4575 registry()->GetExtensionById(good_crx, ExtensionRegistry::COMPATIBILITY));
4576 EXPECT_TRUE(
4577 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]5fdfa562013-12-27 17:43:594578
[email protected]f484f8d52014-06-12 08:38:184579 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4580 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4581 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4582 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
[email protected]cd500f72010-06-25 23:44:324583
4584 // Disable it.
Devlin Cronineea1b7a2018-05-26 02:46:214585 service()->DisableExtension(good_crx, disable_reason::DISABLE_USER_ACTION);
[email protected]cd500f72010-06-25 23:44:324586
David Bertoni58c113a2019-08-02 19:53:264587 EXPECT_TRUE(
4588 registry()->GetExtensionById(good_crx, ExtensionRegistry::COMPATIBILITY));
4589 EXPECT_FALSE(
4590 registry()->GetExtensionById(good_crx, ExtensionRegistry::ENABLED));
[email protected]f484f8d52014-06-12 08:38:184591 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4592 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4593 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4594 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
[email protected]bb1bc9b32013-12-21 03:09:144595}
4596
4597TEST_F(ExtensionServiceTest, TerminateExtension) {
4598 InitializeEmptyExtensionService();
4599
[email protected]f484f8d52014-06-12 08:38:184600 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4601 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4602 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4603 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4604 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
[email protected]bb1bc9b32013-12-21 03:09:144605
4606 TerminateExtension(good_crx);
4607
[email protected]f484f8d52014-06-12 08:38:184608 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4609 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4610 EXPECT_EQ(1u, registry()->terminated_extensions().size());
4611 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
[email protected]fa2416f2011-05-03 08:41:204612}
4613
[email protected]d9a61e12012-11-14 02:43:474614TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
[email protected]fa2416f2011-05-03 08:41:204615 InitializeEmptyExtensionService();
4616
[email protected]f484f8d52014-06-12 08:38:184617 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:204618 TerminateExtension(good_crx);
Devlin Cronineea1b7a2018-05-26 02:46:214619 EXPECT_TRUE(
4620 registry()->GetExtensionById(good_crx, ExtensionRegistry::TERMINATED));
[email protected]fa2416f2011-05-03 08:41:204621
4622 // Disable it.
Devlin Cronineea1b7a2018-05-26 02:46:214623 service()->DisableExtension(good_crx, disable_reason::DISABLE_USER_ACTION);
[email protected]fa2416f2011-05-03 08:41:204624
Devlin Cronineea1b7a2018-05-26 02:46:214625 EXPECT_FALSE(
4626 registry()->GetExtensionById(good_crx, ExtensionRegistry::TERMINATED));
David Bertoni58c113a2019-08-02 19:53:264627 EXPECT_TRUE(
4628 registry()->GetExtensionById(good_crx, ExtensionRegistry::COMPATIBILITY));
[email protected]bb1bc9b32013-12-21 03:09:144629
[email protected]f484f8d52014-06-12 08:38:184630 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4631 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4632 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4633 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
[email protected]cd500f72010-06-25 23:44:324634}
4635
rdevlin.cronin7217be52017-03-24 20:47:054636// Tests that with the kDisableExtensions flag, extensions are not loaded by
4637// the ExtensionService...
4638TEST_F(ExtensionServiceTest, PRE_DisableAllExtensions) {
4639 base::CommandLine::ForCurrentProcess()->AppendSwitch(
Devlin Cronineea1b7a2018-05-26 02:46:214640 ::switches::kDisableExtensions);
rdevlin.cronin7217be52017-03-24 20:47:054641 InitializeGoodInstalledExtensionService();
4642 service()->Init();
4643 EXPECT_TRUE(registry()->GenerateInstalledExtensionsSet()->is_empty());
4644}
4645
4646// ... But, if we remove the switch, they are.
[email protected]d9a61e12012-11-14 02:43:474647TEST_F(ExtensionServiceTest, DisableAllExtensions) {
rdevlin.cronin7217be52017-03-24 20:47:054648 EXPECT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
Devlin Cronineea1b7a2018-05-26 02:46:214649 ::switches::kDisableExtensions));
rdevlin.cronin7217be52017-03-24 20:47:054650 InitializeGoodInstalledExtensionService();
4651 service()->Init();
4652 EXPECT_FALSE(registry()->GenerateInstalledExtensionsSet()->is_empty());
4653 EXPECT_FALSE(registry()->enabled_extensions().is_empty());
[email protected]d728e002010-12-08 04:46:234654}
4655
[email protected]8f512c72011-11-22 21:02:504656// Tests reloading extensions.
[email protected]d9a61e12012-11-14 02:43:474657TEST_F(ExtensionServiceTest, ReloadExtensions) {
[email protected]eaa7dd182010-12-14 11:09:004658 InitializeEmptyExtensionService();
[email protected]cd500f72010-06-25 23:44:324659
4660 // Simple extension that should install without error.
[email protected]f484f8d52014-06-12 08:38:184661 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]26367b62012-10-04 23:03:324662 InstallCRX(path, INSTALL_NEW,
4663 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
thestig4b36dd32014-10-31 20:30:194664 const char* const extension_id = good_crx;
Minh X. Nguyen45479012017-08-18 21:35:364665 service()->DisableExtension(extension_id,
Devlin Cronineea1b7a2018-05-26 02:46:214666 disable_reason::DISABLE_USER_ACTION);
[email protected]cd500f72010-06-25 23:44:324667
[email protected]f484f8d52014-06-12 08:38:184668 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4669 EXPECT_EQ(1u, registry()->disabled_extensions().size());
[email protected]cd500f72010-06-25 23:44:324670
[email protected]f484f8d52014-06-12 08:38:184671 service()->ReloadExtensionsForTest();
[email protected]cd500f72010-06-25 23:44:324672
[email protected]26367b62012-10-04 23:03:324673 // The creation flags should not change when reloading the extension.
David Bertoni58c113a2019-08-02 19:53:264674 const Extension* extension =
4675 registry()->GetExtensionById(good_crx, ExtensionRegistry::COMPATIBILITY);
[email protected]26367b62012-10-04 23:03:324676 EXPECT_TRUE(extension->from_webstore());
4677 EXPECT_TRUE(extension->was_installed_by_default());
4678 EXPECT_FALSE(extension->from_bookmark());
4679
[email protected]cd500f72010-06-25 23:44:324680 // Extension counts shouldn't change.
[email protected]f484f8d52014-06-12 08:38:184681 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4682 EXPECT_EQ(1u, registry()->disabled_extensions().size());
[email protected]cd500f72010-06-25 23:44:324683
[email protected]f484f8d52014-06-12 08:38:184684 service()->EnableExtension(extension_id);
[email protected]cd500f72010-06-25 23:44:324685
[email protected]f484f8d52014-06-12 08:38:184686 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4687 EXPECT_EQ(0u, registry()->disabled_extensions().size());
[email protected]cd500f72010-06-25 23:44:324688
[email protected]5a73f902010-06-30 02:29:414689 // Need to clear |loaded_| manually before reloading as the
4690 // EnableExtension() call above inserted into it and
4691 // UnloadAllExtensions() doesn't send out notifications.
4692 loaded_.clear();
[email protected]f484f8d52014-06-12 08:38:184693 service()->ReloadExtensionsForTest();
[email protected]cd500f72010-06-25 23:44:324694
4695 // Extension counts shouldn't change.
[email protected]f484f8d52014-06-12 08:38:184696 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4697 EXPECT_EQ(0u, registry()->disabled_extensions().size());
[email protected]cd500f72010-06-25 23:44:324698}
4699
[email protected]2a947202013-03-06 04:58:054700// Tests reloading an extension.
4701TEST_F(ExtensionServiceTest, ReloadExtension) {
4702 InitializeEmptyExtensionService();
[email protected]2a947202013-03-06 04:58:054703
4704 // Simple extension that should install without error.
thestig4b36dd32014-10-31 20:30:194705 const char extension_id[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
[email protected]f484f8d52014-06-12 08:38:184706 base::FilePath ext = data_dir()
4707 .AppendASCII("good")
4708 .AppendASCII("Extensions")
4709 .AppendASCII(extension_id)
4710 .AppendASCII("1.0.0.0");
Devlin Cronineea1b7a2018-05-26 02:46:214711 UnpackedInstaller::Create(service())->Load(ext);
Gabriel Charette01507a22017-09-27 21:30:084712 content::RunAllTasksUntilIdle();
[email protected]2a947202013-03-06 04:58:054713
[email protected]f484f8d52014-06-12 08:38:184714 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4715 EXPECT_EQ(0u, registry()->disabled_extensions().size());
[email protected]2a947202013-03-06 04:58:054716
[email protected]f484f8d52014-06-12 08:38:184717 service()->ReloadExtension(extension_id);
[email protected]2a947202013-03-06 04:58:054718
4719 // Extension should be disabled now, waiting to be reloaded.
[email protected]f484f8d52014-06-12 08:38:184720 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4721 EXPECT_EQ(1u, registry()->disabled_extensions().size());
Devlin Cronineea1b7a2018-05-26 02:46:214722 EXPECT_EQ(disable_reason::DISABLE_RELOAD,
[email protected]f484f8d52014-06-12 08:38:184723 ExtensionPrefs::Get(profile())->GetDisableReasons(extension_id));
[email protected]2a947202013-03-06 04:58:054724
[email protected]a5768512013-04-12 19:35:354725 // Reloading again should not crash.
[email protected]f484f8d52014-06-12 08:38:184726 service()->ReloadExtension(extension_id);
[email protected]2a947202013-03-06 04:58:054727
4728 // Finish reloading
Gabriel Charette01507a22017-09-27 21:30:084729 content::RunAllTasksUntilIdle();
[email protected]2a947202013-03-06 04:58:054730
4731 // Extension should be enabled again.
[email protected]f484f8d52014-06-12 08:38:184732 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4733 EXPECT_EQ(0u, registry()->disabled_extensions().size());
[email protected]2a947202013-03-06 04:58:054734}
4735
[email protected]d9a61e12012-11-14 02:43:474736TEST_F(ExtensionServiceTest, UninstallExtension) {
[email protected]eaa7dd182010-12-14 11:09:004737 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:184738 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4739 EXPECT_EQ(1u, registry()->enabled_extensions().size());
Devlin Cronin6fd1cd62017-12-05 19:13:574740 UninstallExtension(good_crx);
[email protected]f484f8d52014-06-12 08:38:184741 EXPECT_EQ(0u, registry()->enabled_extensions().size());
limasdf0deef2042017-05-03 19:17:174742 EXPECT_EQ(UnloadedExtensionReason::UNINSTALL, unloaded_reason_);
[email protected]fa2416f2011-05-03 08:41:204743}
[email protected]631cf822009-05-15 07:01:254744
[email protected]d9a61e12012-11-14 02:43:474745TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
[email protected]fa2416f2011-05-03 08:41:204746 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:184747 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:204748 TerminateExtension(good_crx);
Devlin Cronin6fd1cd62017-12-05 19:13:574749 UninstallExtension(good_crx);
limasdf0deef2042017-05-03 19:17:174750 EXPECT_EQ(UnloadedExtensionReason::TERMINATE, unloaded_reason_);
[email protected]6aeac8342010-10-01 20:21:184751}
4752
[email protected]98270432012-09-11 20:51:244753// An extension disabled because of unsupported requirements should re-enabled
4754// if updated to a version with supported requirements as long as there are no
4755// other disable reasons.
[email protected]d9a61e12012-11-14 02:43:474756TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
[email protected]98270432012-09-11 20:51:244757 InitializeEmptyExtensionService();
zmo2602bcf2017-04-01 00:12:034758 content::GpuDataManager::GetInstance()->BlacklistWebGLForTesting();
[email protected]98270432012-09-11 20:51:244759
[email protected]f484f8d52014-06-12 08:38:184760 base::FilePath path = data_dir().AppendASCII("requirements");
4761 base::FilePath pem_path =
4762 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
[email protected]98270432012-09-11 20:51:244763 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4764 pem_path,
4765 INSTALL_NEW);
4766 std::string id = extension_v1->id();
[email protected]f484f8d52014-06-12 08:38:184767 EXPECT_TRUE(service()->IsExtensionEnabled(id));
[email protected]98270432012-09-11 20:51:244768
[email protected]650b2d52013-02-10 03:41:454769 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
[email protected]a17dfcf2012-12-30 02:07:094770
4771 PackCRX(path.AppendASCII("v2_bad_requirements"),
4772 pem_path,
4773 v2_bad_requirements_crx);
4774 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
[email protected]f484f8d52014-06-12 08:38:184775 EXPECT_FALSE(service()->IsExtensionEnabled(id));
[email protected]98270432012-09-11 20:51:244776
[email protected]650b2d52013-02-10 03:41:454777 base::FilePath v3_good_crx = GetTemporaryFile();
[email protected]a17dfcf2012-12-30 02:07:094778
4779 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4780 UpdateExtension(id, v3_good_crx, ENABLED);
[email protected]f484f8d52014-06-12 08:38:184781 EXPECT_TRUE(service()->IsExtensionEnabled(id));
[email protected]98270432012-09-11 20:51:244782}
4783
4784// Extensions disabled through user action should stay disabled.
[email protected]d9a61e12012-11-14 02:43:474785TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
[email protected]98270432012-09-11 20:51:244786 InitializeEmptyExtensionService();
zmo2602bcf2017-04-01 00:12:034787 content::GpuDataManager::GetInstance()->BlacklistWebGLForTesting();
[email protected]98270432012-09-11 20:51:244788
[email protected]f484f8d52014-06-12 08:38:184789 base::FilePath path = data_dir().AppendASCII("requirements");
4790 base::FilePath pem_path =
4791 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
[email protected]98270432012-09-11 20:51:244792 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4793 pem_path,
4794 INSTALL_NEW);
4795 std::string id = extension_v1->id();
Devlin Cronineea1b7a2018-05-26 02:46:214796 service()->DisableExtension(id, disable_reason::DISABLE_USER_ACTION);
[email protected]f484f8d52014-06-12 08:38:184797 EXPECT_FALSE(service()->IsExtensionEnabled(id));
[email protected]98270432012-09-11 20:51:244798
[email protected]650b2d52013-02-10 03:41:454799 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
[email protected]a17dfcf2012-12-30 02:07:094800
4801 PackCRX(path.AppendASCII("v2_bad_requirements"),
4802 pem_path,
4803 v2_bad_requirements_crx);
4804 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
[email protected]f484f8d52014-06-12 08:38:184805 EXPECT_FALSE(service()->IsExtensionEnabled(id));
[email protected]98270432012-09-11 20:51:244806
[email protected]650b2d52013-02-10 03:41:454807 base::FilePath v3_good_crx = GetTemporaryFile();
[email protected]a17dfcf2012-12-30 02:07:094808
4809 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4810 UpdateExtension(id, v3_good_crx, INSTALLED);
[email protected]f484f8d52014-06-12 08:38:184811 EXPECT_FALSE(service()->IsExtensionEnabled(id));
[email protected]98270432012-09-11 20:51:244812}
4813
4814// The extension should not re-enabled because it was disabled from a
4815// permission increase.
[email protected]d9a61e12012-11-14 02:43:474816TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
[email protected]98270432012-09-11 20:51:244817 InitializeEmptyExtensionService();
zmo2602bcf2017-04-01 00:12:034818 content::GpuDataManager::GetInstance()->BlacklistWebGLForTesting();
[email protected]98270432012-09-11 20:51:244819
[email protected]f484f8d52014-06-12 08:38:184820 base::FilePath path = data_dir().AppendASCII("requirements");
4821 base::FilePath pem_path =
4822 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
[email protected]98270432012-09-11 20:51:244823 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4824 pem_path,
4825 INSTALL_NEW);
4826 std::string id = extension_v1->id();
[email protected]f484f8d52014-06-12 08:38:184827 EXPECT_TRUE(service()->IsExtensionEnabled(id));
[email protected]98270432012-09-11 20:51:244828
[email protected]650b2d52013-02-10 03:41:454829 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
[email protected]a17dfcf2012-12-30 02:07:094830
4831 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
4832 pem_path,
4833 v2_bad_requirements_and_permissions_crx);
4834 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
[email protected]f484f8d52014-06-12 08:38:184835 EXPECT_FALSE(service()->IsExtensionEnabled(id));
[email protected]98270432012-09-11 20:51:244836
[email protected]650b2d52013-02-10 03:41:454837 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
[email protected]a17dfcf2012-12-30 02:07:094838
4839 PackCRX(path.AppendASCII("v3_bad_permissions"),
4840 pem_path,
4841 v3_bad_permissions_crx);
4842 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
[email protected]f484f8d52014-06-12 08:38:184843 EXPECT_FALSE(service()->IsExtensionEnabled(id));
[email protected]98270432012-09-11 20:51:244844}
4845
4846// Unpacked extensions are not allowed to be installed if they have unsupported
4847// requirements.
[email protected]d9a61e12012-11-14 02:43:474848TEST_F(ExtensionServiceTest, UnpackedRequirements) {
[email protected]98270432012-09-11 20:51:244849 InitializeEmptyExtensionService();
zmo2602bcf2017-04-01 00:12:034850 content::GpuDataManager::GetInstance()->BlacklistWebGLForTesting();
[email protected]98270432012-09-11 20:51:244851
[email protected]f484f8d52014-06-12 08:38:184852 base::FilePath path =
4853 data_dir().AppendASCII("requirements").AppendASCII("v2_bad_requirements");
Devlin Cronineea1b7a2018-05-26 02:46:214854 UnpackedInstaller::Create(service())->Load(path);
Gabriel Charette01507a22017-09-27 21:30:084855 content::RunAllTasksUntilIdle();
[email protected]98270432012-09-11 20:51:244856 EXPECT_EQ(1u, GetErrors().size());
[email protected]f484f8d52014-06-12 08:38:184857 EXPECT_EQ(0u, registry()->enabled_extensions().size());
[email protected]98270432012-09-11 20:51:244858}
4859
[email protected]c4148a72011-08-09 23:04:204860class ExtensionCookieCallback {
4861 public:
Gabriel Charettee3769cf2017-07-27 16:52:504862 ExtensionCookieCallback() : result_(false) {}
[email protected]c4148a72011-08-09 23:04:204863
Aaron Tagliaboschi29764f52019-02-21 17:19:594864 void SetCookieCallback(net::CanonicalCookie::CookieInclusionStatus result) {
Lily Chenf53dfbcd2019-08-30 01:42:104865 result_ = result.IsInclude();
[email protected]c4148a72011-08-09 23:04:204866 }
4867
Lily Chenf068a762019-08-21 21:10:504868 void GetAllCookiesCallback(const net::CookieStatusList& list,
Aaron Tagliaboschia4c64b52019-01-25 03:28:494869 const net::CookieStatusList& excluded_list) {
Lily Chenf068a762019-08-21 21:10:504870 list_ = net::cookie_util::StripStatuses(list);
[email protected]c4148a72011-08-09 23:04:204871 }
4872 net::CookieList list_;
4873 bool result_;
[email protected]c4148a72011-08-09 23:04:204874};
4875
Joshua Bell607cb142017-07-24 19:17:164876namespace {
4877// Helper to create (open, close, verify) a WebSQL database.
4878// Must be run on the DatabaseTracker's task runner.
4879void CreateDatabase(storage::DatabaseTracker* db_tracker,
4880 const std::string& origin_id) {
4881 DCHECK(db_tracker->task_runner()->RunsTasksInCurrentSequence());
4882 base::string16 db_name = base::UTF8ToUTF16("db");
4883 base::string16 description = base::UTF8ToUTF16("db_description");
4884 int64_t size;
4885 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4886 db_tracker->DatabaseClosed(origin_id, db_name);
4887 std::vector<storage::OriginInfo> origins;
4888 db_tracker->GetAllOriginsInfo(&origins);
4889 EXPECT_EQ(1U, origins.size());
4890 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4891}
4892} // namespace
4893
[email protected]0d6ec3a72011-09-02 02:09:434894// Verifies extension state is removed upon uninstall.
[email protected]42d58f62014-07-31 01:32:454895TEST_F(ExtensionServiceTest, ClearExtensionData) {
[email protected]eaa7dd182010-12-14 11:09:004896 InitializeEmptyExtensionService();
[email protected]c4148a72011-08-09 23:04:204897 ExtensionCookieCallback callback;
[email protected]c10da4b02010-03-25 14:38:324898
4899 // Load a test extension.
[email protected]f484f8d52014-06-12 08:38:184900 base::FilePath path = data_dir();
[email protected]c10da4b02010-03-25 14:38:324901 path = path.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:504902 const Extension* extension = InstallCRX(path, INSTALL_NEW);
[email protected]c10da4b02010-03-25 14:38:324903 ASSERT_TRUE(extension);
4904 GURL ext_url(extension->url());
[email protected]cd501a72014-08-22 19:58:314905 std::string origin_id = storage::GetIdentifierFromOrigin(ext_url);
[email protected]c10da4b02010-03-25 14:38:324906
4907 // Set a cookie for the extension.
Reilly Grant78e17e32018-09-28 14:35:354908 net::CookieStore* cookie_store =
Maks Orlovich710d5e32019-07-09 20:16:454909 extensions::ChromeExtensionCookies::Get(profile())
4910 ->GetCookieStoreForTesting();
mmenkee28c9aa2016-01-20 23:54:044911 ASSERT_TRUE(cookie_store);
Lily Chen0f208ea2019-08-08 23:37:534912 auto cookie =
4913 net::CanonicalCookie::Create(ext_url, "dummy=value", base::Time::Now(),
4914 base::nullopt /* server_time */);
4915 cookie_store->SetCanonicalCookieAsync(
4916 std::move(cookie), ext_url.scheme(), net::CookieOptions(),
tzik4373d4b2018-03-13 04:42:064917 base::BindOnce(&ExtensionCookieCallback::SetCookieCallback,
4918 base::Unretained(&callback)));
Gabriel Charette01507a22017-09-27 21:30:084919 content::RunAllTasksUntilIdle();
[email protected]c4148a72011-08-09 23:04:204920 EXPECT_TRUE(callback.result_);
4921
Lily Chenf2dc5f02019-08-12 19:43:114922 cookie_store->GetCookieListWithOptionsAsync(
4923 ext_url, net::CookieOptions::MakeAllInclusive(),
4924 base::BindOnce(&ExtensionCookieCallback::GetAllCookiesCallback,
4925 base::Unretained(&callback)));
Gabriel Charette01507a22017-09-27 21:30:084926 content::RunAllTasksUntilIdle();
[email protected]c4148a72011-08-09 23:04:204927 EXPECT_EQ(1U, callback.list_.size());
[email protected]c10da4b02010-03-25 14:38:324928
4929 // Open a database.
[email protected]cd501a72014-08-22 19:58:314930 storage::DatabaseTracker* db_tracker =
[email protected]f484f8d52014-06-12 08:38:184931 BrowserContext::GetDefaultStoragePartition(profile())
4932 ->GetDatabaseTracker();
Joshua Bell607cb142017-07-24 19:17:164933 db_tracker->task_runner()->PostTask(
4934 FROM_HERE,
4935 base::BindOnce(&CreateDatabase, base::Unretained(db_tracker), origin_id));
Gabriel Charette01507a22017-09-27 21:30:084936 content::RunAllTasksUntilIdle();
[email protected]c10da4b02010-03-25 14:38:324937
[email protected]98823c682012-06-11 21:18:244938 // Create local storage. We only simulate this by creating the backing files.
4939 // Note: This test depends on details of how the dom_storage library
4940 // stores data in the host file system.
[email protected]650b2d52013-02-10 03:41:454941 base::FilePath lso_dir_path =
[email protected]f484f8d52014-06-12 08:38:184942 profile()->GetPath().AppendASCII("Local Storage");
[email protected]5e301592013-06-18 06:36:054943 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4944 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
[email protected]426d1c92013-12-03 20:08:544945 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
[email protected]e5c2a22e2014-03-06 20:42:304946 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
[email protected]7567484142013-07-11 17:36:074947 EXPECT_TRUE(base::PathExists(lso_file_path));
[email protected]c10da4b02010-03-25 14:38:324948
[email protected]ab308092011-08-25 23:37:194949 // Create indexed db. Similarly, it is enough to only simulate this by
jsbellbd2caa02017-07-14 01:13:074950 // creating the directory on the disk, and resetting the caches of
4951 // "known" origins.
[email protected]f484f8d52014-06-12 08:38:184952 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4953 profile())->GetIndexedDBContext();
Zhuoyu Qian492f36e52018-12-07 18:32:244954 base::FilePath idb_path =
4955 idb_context->GetFilePathForTesting(url::Origin::Create(ext_url));
[email protected]426d1c92013-12-03 20:08:544956 EXPECT_TRUE(base::CreateDirectory(idb_path));
[email protected]dcd16612013-07-15 20:18:094957 EXPECT_TRUE(base::DirectoryExists(idb_path));
jsbellbd2caa02017-07-14 01:13:074958 idb_context->ResetCachesForTesting();
[email protected]e1dcf922010-11-22 19:12:124959
[email protected]c10da4b02010-03-25 14:38:324960 // Uninstall the extension.
Devlin Cronineea1b7a2018-05-26 02:46:214961 ASSERT_TRUE(service()->UninstallExtension(
4962 good_crx, UNINSTALL_REASON_FOR_TESTING, NULL));
Devlin Cronin218df7f2017-11-21 21:41:314963 // The data deletion happens on the IO thread; since we use a
Gabriel Charette798fde72019-08-20 22:24:044964 // BrowserTaskEnvironment (without REAL_IO_THREAD), the IO and UI threads are
Devlin Cronin218df7f2017-11-21 21:41:314965 // the same, and RunAllTasksUntilIdle() should run IO thread tasks.
4966 content::RunAllTasksUntilIdle();
[email protected]c10da4b02010-03-25 14:38:324967
4968 // Check that the cookie is gone.
Lily Chenf2dc5f02019-08-12 19:43:114969 cookie_store->GetCookieListWithOptionsAsync(
4970 ext_url, net::CookieOptions::MakeAllInclusive(),
4971 base::BindOnce(&ExtensionCookieCallback::GetAllCookiesCallback,
4972 base::Unretained(&callback)));
Gabriel Charette01507a22017-09-27 21:30:084973 content::RunAllTasksUntilIdle();
[email protected]c4148a72011-08-09 23:04:204974 EXPECT_EQ(0U, callback.list_.size());
[email protected]c10da4b02010-03-25 14:38:324975
4976 // The database should have vanished as well.
Joshua Bell607cb142017-07-24 19:17:164977 db_tracker->task_runner()->PostTask(
4978 FROM_HERE, base::BindOnce(
4979 [](storage::DatabaseTracker* db_tracker) {
4980 std::vector<storage::OriginInfo> origins;
4981 db_tracker->GetAllOriginsInfo(&origins);
4982 EXPECT_EQ(0U, origins.size());
4983 },
4984 base::Unretained(db_tracker)));
Gabriel Charette01507a22017-09-27 21:30:084985 content::RunAllTasksUntilIdle();
[email protected]c10da4b02010-03-25 14:38:324986
4987 // Check that the LSO file has been removed.
[email protected]7567484142013-07-11 17:36:074988 EXPECT_FALSE(base::PathExists(lso_file_path));
[email protected]e1dcf922010-11-22 19:12:124989
4990 // Check if the indexed db has disappeared too.
[email protected]dcd16612013-07-15 20:18:094991 EXPECT_FALSE(base::DirectoryExists(idb_path));
[email protected]c10da4b02010-03-25 14:38:324992}
4993
Randy Smithe93faff2017-12-22 14:28:524994void SetCookieSaveData(bool* result_out,
4995 base::OnceClosure callback,
Aaron Tagliaboschi3e464af2019-03-28 18:09:544996 net::CanonicalCookie::CookieInclusionStatus result) {
Lily Chenf53dfbcd2019-08-30 01:42:104997 *result_out = result.IsInclude();
Randy Smithe93faff2017-12-22 14:28:524998 std::move(callback).Run();
4999}
5000
5001void GetCookiesSaveData(std::vector<net::CanonicalCookie>* result_out,
5002 base::OnceClosure callback,
Lily Chenf068a762019-08-21 21:10:505003 const net::CookieStatusList& result,
Aaron Tagliaboschi3e464af2019-03-28 18:09:545004 const net::CookieStatusList& excluded_cookies) {
Lily Chenf068a762019-08-21 21:10:505005 *result_out = net::cookie_util::StripStatuses(result);
Randy Smithe93faff2017-12-22 14:28:525006 std::move(callback).Run();
5007}
5008
[email protected]0d6ec3a72011-09-02 02:09:435009// Verifies app state is removed upon uninstall.
[email protected]d9a61e12012-11-14 02:43:475010TEST_F(ExtensionServiceTest, ClearAppData) {
[email protected]0d6ec3a72011-09-02 02:09:435011 InitializeEmptyExtensionService();
[email protected]0d6ec3a72011-09-02 02:09:435012 ExtensionCookieCallback callback;
5013
5014 int pref_count = 0;
5015
5016 // Install app1 with unlimited storage.
[email protected]8f512c72011-11-22 21:02:505017 const Extension* extension =
[email protected]f484f8d52014-06-12 08:38:185018 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
[email protected]0d6ec3a72011-09-02 02:09:435019 ValidatePrefKeyCount(++pref_count);
[email protected]f484f8d52014-06-12 08:38:185020 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]0d6ec3a72011-09-02 02:09:435021 const std::string id1 = extension->id();
[email protected]076ebeda2014-06-06 21:47:265022 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:065023 APIPermission::kUnlimitedStorage));
Devlin Cronineea1b7a2018-05-26 02:46:215024 const GURL origin1(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
[email protected]f484f8d52014-06-12 08:38:185025 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5026 origin1));
[email protected]cd501a72014-08-22 19:58:315027 std::string origin_id = storage::GetIdentifierFromOrigin(origin1);
[email protected]0d6ec3a72011-09-02 02:09:435028
5029 // Install app2 from the same origin with unlimited storage.
[email protected]f484f8d52014-06-12 08:38:185030 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
[email protected]0d6ec3a72011-09-02 02:09:435031 ValidatePrefKeyCount(++pref_count);
[email protected]f484f8d52014-06-12 08:38:185032 ASSERT_EQ(2u, registry()->enabled_extensions().size());
[email protected]0d6ec3a72011-09-02 02:09:435033 const std::string id2 = extension->id();
[email protected]076ebeda2014-06-06 21:47:265034 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:065035 APIPermission::kUnlimitedStorage));
[email protected]0d6ec3a72011-09-02 02:09:435036 EXPECT_TRUE(extension->web_extent().MatchesURL(
Devlin Cronineea1b7a2018-05-26 02:46:215037 AppLaunchInfo::GetFullLaunchURL(extension)));
5038 const GURL origin2(AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
[email protected]0d6ec3a72011-09-02 02:09:435039 EXPECT_EQ(origin1, origin2);
[email protected]f484f8d52014-06-12 08:38:185040 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5041 origin2));
[email protected]0d6ec3a72011-09-02 02:09:435042
John Abd-El-Malek53670dd2018-01-18 22:07:215043 network::mojom::NetworkContext* network_context =
Randy Smithe93faff2017-12-22 14:28:525044 content::BrowserContext::GetDefaultStoragePartition(profile())
5045 ->GetNetworkContext();
Julie Jeongeun Kimc0827552019-08-27 03:19:375046 mojo::Remote<network::mojom::CookieManager> cookie_manager_remote;
5047 network_context->GetCookieManager(
5048 cookie_manager_remote.BindNewPipeAndPassReceiver());
[email protected]0d6ec3a72011-09-02 02:09:435049
Lily Chenb851acc2019-08-07 15:54:445050 std::unique_ptr<net::CanonicalCookie> cc(
5051 net::CanonicalCookie::Create(origin1, "dummy=value", base::Time::Now(),
5052 base::nullopt /* server_time */));
Randy Smithe93faff2017-12-22 14:28:525053 ASSERT_TRUE(cc.get());
5054
5055 {
5056 bool set_result = false;
5057 base::RunLoop run_loop;
Julie Jeongeun Kimc0827552019-08-27 03:19:375058 cookie_manager_remote->SetCanonicalCookie(
Maks Orlovichfdbc8be2019-03-18 18:34:525059 *cc.get(), origin1.scheme(), net::CookieOptions(),
Randy Smithe93faff2017-12-22 14:28:525060 base::BindOnce(&SetCookieSaveData, &set_result,
5061 run_loop.QuitClosure()));
5062 run_loop.Run();
5063 EXPECT_TRUE(set_result);
5064 }
5065
5066 {
5067 base::RunLoop run_loop;
5068 std::vector<net::CanonicalCookie> cookies_result;
Julie Jeongeun Kimc0827552019-08-27 03:19:375069 cookie_manager_remote->GetCookieList(
Randy Smithe93faff2017-12-22 14:28:525070 origin1, net::CookieOptions(),
5071 base::BindOnce(&GetCookiesSaveData, &cookies_result,
5072 run_loop.QuitClosure()));
5073 run_loop.Run();
5074 EXPECT_EQ(1U, cookies_result.size());
5075 }
[email protected]0d6ec3a72011-09-02 02:09:435076
5077 // Open a database.
[email protected]cd501a72014-08-22 19:58:315078 storage::DatabaseTracker* db_tracker =
[email protected]f484f8d52014-06-12 08:38:185079 BrowserContext::GetDefaultStoragePartition(profile())
5080 ->GetDatabaseTracker();
Joshua Bell607cb142017-07-24 19:17:165081 db_tracker->task_runner()->PostTask(
5082 FROM_HERE,
5083 base::BindOnce(&CreateDatabase, base::Unretained(db_tracker), origin_id));
Gabriel Charette01507a22017-09-27 21:30:085084 content::RunAllTasksUntilIdle();
[email protected]0d6ec3a72011-09-02 02:09:435085
[email protected]98823c682012-06-11 21:18:245086 // Create local storage. We only simulate this by creating the backing files.
5087 // Note: This test depends on details of how the dom_storage library
5088 // stores data in the host file system.
[email protected]650b2d52013-02-10 03:41:455089 base::FilePath lso_dir_path =
[email protected]f484f8d52014-06-12 08:38:185090 profile()->GetPath().AppendASCII("Local Storage");
[email protected]5e301592013-06-18 06:36:055091 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
5092 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
[email protected]426d1c92013-12-03 20:08:545093 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
[email protected]e5c2a22e2014-03-06 20:42:305094 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
[email protected]7567484142013-07-11 17:36:075095 EXPECT_TRUE(base::PathExists(lso_file_path));
[email protected]0d6ec3a72011-09-02 02:09:435096
5097 // Create indexed db. Similarly, it is enough to only simulate this by
jsbellbd2caa02017-07-14 01:13:075098 // creating the directory on the disk, and resetting the caches of
5099 // "known" origins.
[email protected]f484f8d52014-06-12 08:38:185100 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
5101 profile())->GetIndexedDBContext();
Zhuoyu Qian492f36e52018-12-07 18:32:245102 base::FilePath idb_path =
5103 idb_context->GetFilePathForTesting(url::Origin::Create(origin1));
[email protected]426d1c92013-12-03 20:08:545104 EXPECT_TRUE(base::CreateDirectory(idb_path));
[email protected]dcd16612013-07-15 20:18:095105 EXPECT_TRUE(base::DirectoryExists(idb_path));
jsbellbd2caa02017-07-14 01:13:075106 idb_context->ResetCachesForTesting();
[email protected]0d6ec3a72011-09-02 02:09:435107
5108 // Uninstall one of them, unlimited storage should still be granted
5109 // to the origin.
Devlin Cronin6fd1cd62017-12-05 19:13:575110 UninstallExtension(id1);
[email protected]f484f8d52014-06-12 08:38:185111 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5112 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5113 origin1));
[email protected]0d6ec3a72011-09-02 02:09:435114
Randy Smithe93faff2017-12-22 14:28:525115 {
5116 // Check that the cookie is still there.
5117 base::RunLoop run_loop;
5118 std::vector<net::CanonicalCookie> cookies_result;
Julie Jeongeun Kimc0827552019-08-27 03:19:375119 cookie_manager_remote->GetCookieList(
Randy Smithe93faff2017-12-22 14:28:525120 origin1, net::CookieOptions(),
5121 base::BindOnce(&GetCookiesSaveData, &cookies_result,
5122 run_loop.QuitClosure()));
5123 run_loop.Run();
5124 EXPECT_EQ(1U, cookies_result.size());
5125 }
[email protected]0d6ec3a72011-09-02 02:09:435126
5127 // Now uninstall the other. Storage should be cleared for the apps.
Devlin Cronin6fd1cd62017-12-05 19:13:575128 UninstallExtension(id2);
[email protected]f484f8d52014-06-12 08:38:185129 EXPECT_EQ(0u, registry()->enabled_extensions().size());
5130 EXPECT_FALSE(
5131 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5132 origin1));
[email protected]0d6ec3a72011-09-02 02:09:435133
Randy Smithe93faff2017-12-22 14:28:525134 {
5135 // Check that the cookie is gone.
5136 base::RunLoop run_loop;
5137 std::vector<net::CanonicalCookie> cookies_result;
Julie Jeongeun Kimc0827552019-08-27 03:19:375138 cookie_manager_remote->GetCookieList(
Randy Smithe93faff2017-12-22 14:28:525139 origin1, net::CookieOptions(),
5140 base::BindOnce(&GetCookiesSaveData, &cookies_result,
5141 run_loop.QuitClosure()));
5142 run_loop.Run();
5143 EXPECT_EQ(0U, cookies_result.size());
5144 }
[email protected]0d6ec3a72011-09-02 02:09:435145
5146 // The database should have vanished as well.
Joshua Bell607cb142017-07-24 19:17:165147 db_tracker->task_runner()->PostTask(
5148 FROM_HERE, base::BindOnce(
5149 [](storage::DatabaseTracker* db_tracker) {
5150 std::vector<storage::OriginInfo> origins;
5151 db_tracker->GetAllOriginsInfo(&origins);
5152 EXPECT_EQ(0U, origins.size());
5153 },
5154 base::Unretained(db_tracker)));
Gabriel Charette01507a22017-09-27 21:30:085155 content::RunAllTasksUntilIdle();
[email protected]0d6ec3a72011-09-02 02:09:435156
5157 // Check that the LSO file has been removed.
[email protected]7567484142013-07-11 17:36:075158 EXPECT_FALSE(base::PathExists(lso_file_path));
[email protected]0d6ec3a72011-09-02 02:09:435159
5160 // Check if the indexed db has disappeared too.
[email protected]dcd16612013-07-15 20:18:095161 EXPECT_FALSE(base::DirectoryExists(idb_path));
[email protected]0d6ec3a72011-09-02 02:09:435162}
5163
[email protected]894bb502009-05-21 22:39:575164// Tests loading single extensions (like --load-extension)
Devlin Cronina7baea22017-12-12 14:43:055165TEST_F(ExtensionServiceTest, LoadExtension) {
[email protected]eaa7dd182010-12-14 11:09:005166 InitializeEmptyExtensionService();
Devlin Cronineea1b7a2018-05-26 02:46:215167 TestExtensionDir good_extension_dir;
Devlin Cronina7baea22017-12-12 14:43:055168 good_extension_dir.WriteManifest(
5169 R"({
5170 "name": "Good Extension",
5171 "version": "0.1",
5172 "manifest_version": 2
5173 })");
[email protected]3cf4f0992009-02-03 23:00:305174
Devlin Cronina7baea22017-12-12 14:43:055175 {
Devlin Cronineea1b7a2018-05-26 02:46:215176 ChromeTestExtensionLoader loader(profile());
Devlin Cronina7baea22017-12-12 14:43:055177 loader.set_pack_extension(false);
5178 loader.LoadExtension(good_extension_dir.UnpackedPath());
5179 }
[email protected]bb28e062009-02-27 17:19:185180 EXPECT_EQ(0u, GetErrors().size());
[email protected]f484f8d52014-06-12 08:38:185181 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]e8c729a2010-03-09 19:55:195182 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:195183
Devlin Cronineea1b7a2018-05-26 02:46:215184 auto get_extension_by_name = [](const ExtensionSet& extensions,
Devlin Cronina7baea22017-12-12 14:43:055185 const std::string& name) {
5186 // NOTE: lambda type deduction doesn't recognize returning
5187 // const Extension* in one place and nullptr in another as the same type, so
5188 // we have to make sure to return an explicit type here.
Devlin Cronineea1b7a2018-05-26 02:46:215189 const Extension* result = nullptr;
Devlin Cronina7baea22017-12-12 14:43:055190 for (const auto& extension : extensions) {
5191 if (extension->name() == name) {
5192 result = extension.get();
5193 break;
5194 }
5195 }
5196 return result;
5197 };
5198 constexpr const char kGoodExtension[] = "Good Extension";
5199 {
5200 const Extension* extension =
5201 get_extension_by_name(registry()->enabled_extensions(), kGoodExtension);
5202 ASSERT_TRUE(extension);
5203 EXPECT_EQ(Manifest::UNPACKED, extension->location());
5204 }
[email protected]25b34332009-06-05 21:53:195205
Devlin Cronina7baea22017-12-12 14:43:055206 // Try loading an extension with no manifest. It should fail.
Devlin Cronineea1b7a2018-05-26 02:46:215207 TestExtensionDir bad_extension_dir;
Devlin Cronina7baea22017-12-12 14:43:055208 bad_extension_dir.WriteFile(FILE_PATH_LITERAL("background.js"), "// some JS");
5209 {
Devlin Cronineea1b7a2018-05-26 02:46:215210 ChromeTestExtensionLoader loader(profile());
Devlin Cronina7baea22017-12-12 14:43:055211 loader.set_pack_extension(false);
5212 loader.set_should_fail(true);
5213 loader.LoadExtension(bad_extension_dir.UnpackedPath());
5214 }
5215
5216 EXPECT_EQ(1u, GetErrors().size());
5217 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5218 EXPECT_EQ(1u, registry()->GenerateInstalledExtensionsSet()->size());
5219 EXPECT_TRUE(
5220 get_extension_by_name(registry()->enabled_extensions(), kGoodExtension));
5221
5222 // Test uninstalling the good extension.
Devlin Cronineea1b7a2018-05-26 02:46:215223 const ExtensionId good_id =
Devlin Cronina7baea22017-12-12 14:43:055224 get_extension_by_name(registry()->enabled_extensions(), kGoodExtension)
5225 ->id();
Devlin Cronineea1b7a2018-05-26 02:46:215226 service()->UninstallExtension(good_id, UNINSTALL_REASON_FOR_TESTING, nullptr);
Gabriel Charette01507a22017-09-27 21:30:085227 content::RunAllTasksUntilIdle();
Devlin Cronina7baea22017-12-12 14:43:055228 EXPECT_TRUE(registry()->GenerateInstalledExtensionsSet()->is_empty());
[email protected]3cf4f0992009-02-03 23:00:305229}
[email protected]0b344962009-03-31 04:21:455230
[email protected]894bb502009-05-21 22:39:575231// Tests that we generate IDs when they are not specified in the manifest for
5232// --load-extension.
[email protected]d9a61e12012-11-14 02:43:475233TEST_F(ExtensionServiceTest, GenerateID) {
[email protected]eaa7dd182010-12-14 11:09:005234 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:455235
[email protected]f484f8d52014-06-12 08:38:185236 base::FilePath no_id_ext = data_dir().AppendASCII("no_id");
Devlin Cronineea1b7a2018-05-26 02:46:215237 UnpackedInstaller::Create(service())->Load(no_id_ext);
Gabriel Charette01507a22017-09-27 21:30:085238 content::RunAllTasksUntilIdle();
[email protected]0b344962009-03-31 04:21:455239 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:575240 ASSERT_EQ(1u, loaded_.size());
[email protected]fdd28372014-08-21 02:27:265241 ASSERT_TRUE(crx_file::id_util::IdIsValid(loaded_[0]->id()));
[email protected]12075d12013-02-27 05:38:055242 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
[email protected]0b344962009-03-31 04:21:455243
[email protected]e8c729a2010-03-09 19:55:195244 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:195245
[email protected]84ac7f32009-10-06 06:17:545246 std::string previous_id = loaded_[0]->id();
5247
5248 // If we reload the same path, we should get the same extension ID.
Devlin Cronineea1b7a2018-05-26 02:46:215249 UnpackedInstaller::Create(service())->Load(no_id_ext);
Gabriel Charette01507a22017-09-27 21:30:085250 content::RunAllTasksUntilIdle();
[email protected]84ac7f32009-10-06 06:17:545251 ASSERT_EQ(1u, loaded_.size());
5252 ASSERT_EQ(previous_id, loaded_[0]->id());
[email protected]0b344962009-03-31 04:21:455253}
[email protected]894bb502009-05-21 22:39:575254
[email protected]557c7bd2013-09-18 21:51:255255TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
5256 InitializeEmptyExtensionService();
5257
[email protected]f484f8d52014-06-12 08:38:185258 base::FilePath bad_locale =
5259 data_dir().AppendASCII("unpacked").AppendASCII("bad_messages_file");
Devlin Cronineea1b7a2018-05-26 02:46:215260 UnpackedInstaller::Create(service())->Load(bad_locale);
Gabriel Charette01507a22017-09-27 21:30:085261 content::RunAllTasksUntilIdle();
[email protected]557c7bd2013-09-18 21:51:255262 EXPECT_EQ(1u, GetErrors().size());
5263 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
5264 .AppendASCII("ms")
5265 .AppendASCII("messages.json");
[email protected]04338722013-12-24 23:18:055266 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
5267 testing::HasSubstr(
5268 base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
[email protected]557c7bd2013-09-18 21:51:255269 testing::HasSubstr("Dictionary keys must be quoted.")));
5270 ASSERT_EQ(0u, loaded_.size());
5271}
5272
lazyboya00eafc2017-04-08 00:57:195273void ExtensionServiceTest::TestExternalProvider(MockExternalProvider* provider,
5274 Manifest::Location location) {
[email protected]a1257b12009-06-12 02:51:345275 // Verify that starting with no providers loads no extensions.
[email protected]f484f8d52014-06-12 08:38:185276 service()->Init();
[email protected]a1257b12009-06-12 02:51:345277 ASSERT_EQ(0u, loaded_.size());
5278
[email protected]0a60a2e2010-10-25 16:15:215279 provider->set_visit_count(0);
5280
[email protected]a1257b12009-06-12 02:51:345281 // Register a test extension externally using the mock registry provider.
[email protected]f484f8d52014-06-12 08:38:185282 base::FilePath source_path = data_dir().AppendASCII("good.crx");
[email protected]894bb502009-05-21 22:39:575283
[email protected]a1257b12009-06-12 02:51:345284 // Add the extension.
[email protected]d55e7602009-12-16 04:20:425285 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
[email protected]894bb502009-05-21 22:39:575286
[email protected]9f1087e2009-06-15 17:29:325287 // Reloading extensions should find our externally registered extension
[email protected]894bb502009-05-21 22:39:575288 // and install it.
lazyboy8a08c9d2017-04-11 19:53:225289 WaitForExternalExtensionInstalled();
[email protected]894bb502009-05-21 22:39:575290
5291 ASSERT_EQ(0u, GetErrors().size());
5292 ASSERT_EQ(1u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:425293 ASSERT_EQ(location, loaded_[0]->location());
Devlin Cronin03bf2d22017-12-20 08:21:055294 ASSERT_EQ("1.0.0.0", loaded_[0]->version().GetString());
Devlin Cronin55fab54d2017-12-16 02:27:195295 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
5296 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
5297 // TODO(devlin): Testing the underlying values of the prefs for extensions
5298 // should be done in an ExtensionPrefs test, not here. This should only be
5299 // using the public ExtensionPrefs interfaces.
[email protected]e2194742010-08-12 05:54:345300 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5301 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:575302
[email protected]9f1087e2009-06-15 17:29:325303 // Reload extensions without changing anything. The extension should be
[email protected]894bb502009-05-21 22:39:575304 // loaded again.
5305 loaded_.clear();
[email protected]f484f8d52014-06-12 08:38:185306 service()->ReloadExtensionsForTest();
Gabriel Charette01507a22017-09-27 21:30:085307 content::RunAllTasksUntilIdle();
[email protected]894bb502009-05-21 22:39:575308 ASSERT_EQ(0u, GetErrors().size());
5309 ASSERT_EQ(1u, loaded_.size());
Devlin Cronin55fab54d2017-12-16 02:27:195310 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
[email protected]e2194742010-08-12 05:54:345311 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5312 ValidateIntegerPref(good_crx, "location", location);
[email protected]e2eb43112009-05-29 21:19:545313
[email protected]894bb502009-05-21 22:39:575314 // Now update the extension with a new version. We should get upgraded.
5315 source_path = source_path.DirName().AppendASCII("good2.crx");
[email protected]d55e7602009-12-16 04:20:425316 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
[email protected]894bb502009-05-21 22:39:575317
5318 loaded_.clear();
lazyboy8a08c9d2017-04-11 19:53:225319 WaitForExternalExtensionInstalled();
[email protected]894bb502009-05-21 22:39:575320 ASSERT_EQ(0u, GetErrors().size());
5321 ASSERT_EQ(1u, loaded_.size());
Devlin Cronin03bf2d22017-12-20 08:21:055322 ASSERT_EQ("1.0.0.1", loaded_[0]->version().GetString());
Devlin Cronin55fab54d2017-12-16 02:27:195323 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
[email protected]e2194742010-08-12 05:54:345324 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5325 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:575326
[email protected]27b985d2009-06-25 17:53:155327 // Uninstall the extension and reload. Nothing should happen because the
[email protected]894bb502009-05-21 22:39:575328 // preference should prevent us from reinstalling.
5329 std::string id = loaded_[0]->id();
Devlin Cronin55fab54d2017-12-16 02:27:195330 EXPECT_EQ(id, good_crx);
[email protected]dc24976f2013-06-02 21:15:095331 bool no_uninstall =
[email protected]f484f8d52014-06-12 08:38:185332 GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL);
Devlin Cronineea1b7a2018-05-26 02:46:215333 service()->UninstallExtension(id, UNINSTALL_REASON_FOR_TESTING, NULL);
Gabriel Charette01507a22017-09-27 21:30:085334 content::RunAllTasksUntilIdle();
[email protected]894bb502009-05-21 22:39:575335
[email protected]f484f8d52014-06-12 08:38:185336 base::FilePath install_path = extensions_install_dir().AppendASCII(id);
[email protected]e410b5f2012-12-14 14:02:245337 if (no_uninstall) {
[email protected]65187152012-06-02 13:14:145338 // Policy controlled extensions should not have been touched by uninstall.
[email protected]7567484142013-07-11 17:36:075339 ASSERT_TRUE(base::PathExists(install_path));
Devlin Cronin55fab54d2017-12-16 02:27:195340 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
5341 EXPECT_FALSE(prefs->IsExternalExtensionUninstalled(good_crx));
[email protected]65187152012-06-02 13:14:145342 } else {
[email protected]95da88c42011-03-31 10:07:335343 // The extension should also be gone from the install directory.
[email protected]7567484142013-07-11 17:36:075344 ASSERT_FALSE(base::PathExists(install_path));
[email protected]95da88c42011-03-31 10:07:335345 loaded_.clear();
[email protected]f484f8d52014-06-12 08:38:185346 service()->CheckForExternalUpdates();
Gabriel Charette01507a22017-09-27 21:30:085347 content::RunAllTasksUntilIdle();
[email protected]95da88c42011-03-31 10:07:335348 ASSERT_EQ(0u, loaded_.size());
Devlin Cronin55fab54d2017-12-16 02:27:195349 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
5350 EXPECT_FALSE(prefs->GetInstalledExtensionInfo(good_crx));
[email protected]894bb502009-05-21 22:39:575351
[email protected]95da88c42011-03-31 10:07:335352 // Now clear the preference and reinstall.
Devlin Cronin55fab54d2017-12-16 02:27:195353 prefs->ClearExternalUninstallForTesting(good_crx);
[email protected]25b34332009-06-05 21:53:195354
[email protected]95da88c42011-03-31 10:07:335355 loaded_.clear();
lazyboy8a08c9d2017-04-11 19:53:225356 WaitForExternalExtensionInstalled();
[email protected]95da88c42011-03-31 10:07:335357 ASSERT_EQ(1u, loaded_.size());
[email protected]95da88c42011-03-31 10:07:335358 }
Devlin Cronin55fab54d2017-12-16 02:27:195359 EXPECT_TRUE(prefs->GetInstalledExtensionInfo(good_crx));
5360 EXPECT_FALSE(prefs->IsExternalExtensionUninstalled(good_crx));
[email protected]e2194742010-08-12 05:54:345361 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5362 ValidateIntegerPref(good_crx, "location", location);
[email protected]25b34332009-06-05 21:53:195363
[email protected]f484f8d52014-06-12 08:38:185364 if (GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL)) {
[email protected]65187152012-06-02 13:14:145365 EXPECT_EQ(2, provider->visit_count());
5366 } else {
[email protected]95da88c42011-03-31 10:07:335367 // Now test an externally triggered uninstall (deleting the registry key or
5368 // the pref entry).
5369 provider->RemoveExtension(good_crx);
[email protected]25b34332009-06-05 21:53:195370
[email protected]95da88c42011-03-31 10:07:335371 loaded_.clear();
[email protected]f484f8d52014-06-12 08:38:185372 service()->OnExternalProviderReady(provider);
Gabriel Charette01507a22017-09-27 21:30:085373 content::RunAllTasksUntilIdle();
[email protected]95da88c42011-03-31 10:07:335374 ASSERT_EQ(0u, loaded_.size());
Devlin Cronin55fab54d2017-12-16 02:27:195375 EXPECT_FALSE(prefs->IsExternalExtensionUninstalled(good_crx));
5376 EXPECT_FALSE(prefs->GetInstalledExtensionInfo(good_crx));
[email protected]25b34332009-06-05 21:53:195377
[email protected]95da88c42011-03-31 10:07:335378 // The extension should also be gone from the install directory.
[email protected]7567484142013-07-11 17:36:075379 ASSERT_FALSE(base::PathExists(install_path));
[email protected]abe7a8942009-06-23 05:14:295380
[email protected]95da88c42011-03-31 10:07:335381 // Now test the case where user uninstalls and then the extension is removed
5382 // from the external provider.
[email protected]05aad2da2011-10-28 10:12:375383 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
lazyboy8a08c9d2017-04-11 19:53:225384 WaitForExternalExtensionInstalled();
[email protected]abe7a8942009-06-23 05:14:295385
[email protected]95da88c42011-03-31 10:07:335386 ASSERT_EQ(1u, loaded_.size());
5387 ASSERT_EQ(0u, GetErrors().size());
[email protected]d55e7602009-12-16 04:20:425388
[email protected]95da88c42011-03-31 10:07:335389 // User uninstalls.
5390 loaded_.clear();
Devlin Cronineea1b7a2018-05-26 02:46:215391 service()->UninstallExtension(id, UNINSTALL_REASON_FOR_TESTING, NULL);
Gabriel Charette01507a22017-09-27 21:30:085392 content::RunAllTasksUntilIdle();
[email protected]95da88c42011-03-31 10:07:335393 ASSERT_EQ(0u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:425394
[email protected]95da88c42011-03-31 10:07:335395 // Then remove the extension from the extension provider.
5396 provider->RemoveExtension(good_crx);
[email protected]d55e7602009-12-16 04:20:425397
[email protected]95da88c42011-03-31 10:07:335398 // Should still be at 0.
5399 loaded_.clear();
rdevlin.croninf2e1cb012017-05-27 01:27:595400 service()->ReloadExtensionsForTest();
Gabriel Charette01507a22017-09-27 21:30:085401 content::RunAllTasksUntilIdle();
[email protected]95da88c42011-03-31 10:07:335402 ASSERT_EQ(0u, loaded_.size());
Devlin Cronin55fab54d2017-12-16 02:27:195403
5404 EXPECT_FALSE(prefs->GetInstalledExtensionInfo(good_crx));
5405 EXPECT_TRUE(prefs->IsExternalExtensionUninstalled(good_crx));
[email protected]0a60a2e2010-10-25 16:15:215406
[email protected]95da88c42011-03-31 10:07:335407 EXPECT_EQ(5, provider->visit_count());
[email protected]95da88c42011-03-31 10:07:335408 }
[email protected]d55e7602009-12-16 04:20:425409}
5410
5411// Tests the external installation feature
5412#if defined(OS_WIN)
[email protected]d9a61e12012-11-14 02:43:475413TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
[email protected]aebe23a32010-12-10 22:15:485414 // This should all work, even when normal extension installation is disabled.
rdevlin.cronin7217be52017-03-24 20:47:055415 InitializeExtensionServiceWithExtensionsDisabled();
[email protected]d55e7602009-12-16 04:20:425416
5417 // Now add providers. Extension system takes ownership of the objects.
lazyboya00eafc2017-04-08 00:57:195418 MockExternalProvider* reg_provider =
lazyboy8a08c9d2017-04-11 19:53:225419 AddMockExternalProvider(Manifest::EXTERNAL_REGISTRY);
[email protected]1d5e58b2013-01-31 08:41:405420 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
[email protected]d55e7602009-12-16 04:20:425421}
5422#endif
5423
[email protected]d9a61e12012-11-14 02:43:475424TEST_F(ExtensionServiceTest, ExternalInstallPref) {
[email protected]eaa7dd182010-12-14 11:09:005425 InitializeEmptyExtensionService();
[email protected]d55e7602009-12-16 04:20:425426
5427 // Now add providers. Extension system takes ownership of the objects.
lazyboya00eafc2017-04-08 00:57:195428 MockExternalProvider* pref_provider =
lazyboy8a08c9d2017-04-11 19:53:225429 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]0a60a2e2010-10-25 16:15:215430
[email protected]1d5e58b2013-01-31 08:41:405431 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
[email protected]27b985d2009-06-25 17:53:155432}
5433
[email protected]d9a61e12012-11-14 02:43:475434TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
[email protected]aebe23a32010-12-10 22:15:485435 // This should all work, even when normal extension installation is disabled.
rdevlin.cronin7217be52017-03-24 20:47:055436 InitializeExtensionServiceWithExtensionsDisabled();
[email protected]55196e92010-09-29 15:04:465437
[email protected]0a60a2e2010-10-25 16:15:215438 // TODO(skerner): The mock provider is not a good model of a provider
5439 // that works with update URLs, because it adds file and version info.
5440 // Extend the mock to work with update URLs. This test checks the
5441 // behavior that is common to all external extension visitors. The
5442 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5443 // what the visitor does results in an extension being downloaded and
5444 // installed.
lazyboya00eafc2017-04-08 00:57:195445 MockExternalProvider* pref_provider =
lazyboy8a08c9d2017-04-11 19:53:225446 AddMockExternalProvider(Manifest::EXTERNAL_PREF_DOWNLOAD);
[email protected]1d5e58b2013-01-31 08:41:405447 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
[email protected]55196e92010-09-29 15:04:465448}
5449
[email protected]d9a61e12012-11-14 02:43:475450TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
[email protected]95da88c42011-03-31 10:07:335451 // This should all work, even when normal extension installation is disabled.
rdevlin.cronin7217be52017-03-24 20:47:055452 InitializeExtensionServiceWithExtensionsDisabled();
[email protected]95da88c42011-03-31 10:07:335453
5454 // TODO(skerner): The mock provider is not a good model of a provider
5455 // that works with update URLs, because it adds file and version info.
5456 // Extend the mock to work with update URLs. This test checks the
5457 // behavior that is common to all external extension visitors. The
5458 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5459 // what the visitor does results in an extension being downloaded and
5460 // installed.
lazyboya00eafc2017-04-08 00:57:195461 MockExternalProvider* pref_provider =
lazyboy8a08c9d2017-04-11 19:53:225462 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
[email protected]1d5e58b2013-01-31 08:41:405463 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
[email protected]95da88c42011-03-31 10:07:335464}
5465
[email protected]aebe23a32010-12-10 22:15:485466// Tests that external extensions get uninstalled when the external extension
5467// providers can't account for them.
[email protected]d9a61e12012-11-14 02:43:475468TEST_F(ExtensionServiceTest, ExternalUninstall) {
[email protected]aebe23a32010-12-10 22:15:485469 // Start the extensions service with one external extension already installed.
[email protected]f484f8d52014-06-12 08:38:185470 base::FilePath source_install_dir =
5471 data_dir().AppendASCII("good").AppendASCII("Extensions");
[email protected]650b2d52013-02-10 03:41:455472 base::FilePath pref_path = source_install_dir
[email protected]aebe23a32010-12-10 22:15:485473 .DirName()
5474 .AppendASCII("PreferencesExternal");
5475
[email protected]eaa7dd182010-12-14 11:09:005476 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]f484f8d52014-06-12 08:38:185477 service()->Init();
[email protected]aebe23a32010-12-10 22:15:485478
5479 ASSERT_EQ(0u, GetErrors().size());
[email protected]1f4728f2012-12-05 20:40:055480 ASSERT_EQ(0u, loaded_.size());
[email protected]aebe23a32010-12-10 22:15:485481}
5482
[email protected]a29a517a2011-01-21 21:11:125483// Test that running multiple update checks simultaneously does not
5484// keep the update from succeeding.
[email protected]d9a61e12012-11-14 02:43:475485TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
[email protected]a29a517a2011-01-21 21:11:125486 InitializeEmptyExtensionService();
5487
lazyboya00eafc2017-04-08 00:57:195488 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:225489 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]a29a517a2011-01-21 21:11:125490
5491 // Verify that starting with no providers loads no extensions.
[email protected]f484f8d52014-06-12 08:38:185492 service()->Init();
[email protected]a29a517a2011-01-21 21:11:125493 ASSERT_EQ(0u, loaded_.size());
5494
5495 // Start two checks for updates.
5496 provider->set_visit_count(0);
[email protected]f484f8d52014-06-12 08:38:185497 service()->CheckForExternalUpdates();
5498 service()->CheckForExternalUpdates();
Gabriel Charette01507a22017-09-27 21:30:085499 content::RunAllTasksUntilIdle();
[email protected]a29a517a2011-01-21 21:11:125500
5501 // Two calls should cause two checks for external extensions.
5502 EXPECT_EQ(2, provider->visit_count());
5503 EXPECT_EQ(0u, GetErrors().size());
5504 EXPECT_EQ(0u, loaded_.size());
5505
5506 // Register a test extension externally using the mock registry provider.
[email protected]f484f8d52014-06-12 08:38:185507 base::FilePath source_path = data_dir().AppendASCII("good.crx");
[email protected]a29a517a2011-01-21 21:11:125508 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5509
5510 // Two checks for external updates should find the extension, and install it
5511 // once.
[email protected]97d6a5c2013-11-11 23:51:245512 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:215513 NOTIFICATION_CRX_INSTALLER_DONE,
[email protected]97d6a5c2013-11-11 23:51:245514 content::NotificationService::AllSources());
[email protected]a29a517a2011-01-21 21:11:125515 provider->set_visit_count(0);
[email protected]f484f8d52014-06-12 08:38:185516 service()->CheckForExternalUpdates();
5517 service()->CheckForExternalUpdates();
[email protected]97d6a5c2013-11-11 23:51:245518 observer.Wait();
[email protected]a29a517a2011-01-21 21:11:125519 EXPECT_EQ(2, provider->visit_count());
5520 ASSERT_EQ(0u, GetErrors().size());
5521 ASSERT_EQ(1u, loaded_.size());
[email protected]1d5e58b2013-01-31 08:41:405522 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
Devlin Cronin03bf2d22017-12-20 08:21:055523 ASSERT_EQ("1.0.0.0", loaded_[0]->version().GetString());
[email protected]a29a517a2011-01-21 21:11:125524 ValidatePrefKeyCount(1);
5525 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:405526 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
[email protected]a29a517a2011-01-21 21:11:125527
5528 provider->RemoveExtension(good_crx);
5529 provider->set_visit_count(0);
[email protected]f484f8d52014-06-12 08:38:185530 service()->CheckForExternalUpdates();
5531 service()->CheckForExternalUpdates();
Gabriel Charette01507a22017-09-27 21:30:085532 content::RunAllTasksUntilIdle();
[email protected]a29a517a2011-01-21 21:11:125533
5534 // Two calls should cause two checks for external extensions.
5535 // Because the external source no longer includes good_crx,
5536 // good_crx will be uninstalled. So, expect that no extensions
5537 // are loaded.
5538 EXPECT_EQ(2, provider->visit_count());
5539 EXPECT_EQ(0u, GetErrors().size());
5540 EXPECT_EQ(0u, loaded_.size());
5541}
5542
[email protected]d9a61e12012-11-14 02:43:475543TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
[email protected]eaa7dd182010-12-14 11:09:005544 InitializeEmptyExtensionService();
[email protected]f0841cd2011-01-19 15:07:245545
5546 // Test some valid extension records.
5547 // Set a base path to avoid erroring out on relative paths.
5548 // Paths starting with // are absolute on every platform we support.
[email protected]650b2d52013-02-10 03:41:455549 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
[email protected]f0841cd2011-01-19 15:07:245550 ASSERT_TRUE(base_path.IsAbsolute());
5551 MockProviderVisitor visitor(base_path);
[email protected]27b985d2009-06-25 17:53:155552 std::string json_data =
5553 "{"
[email protected]f0841cd2011-01-19 15:07:245554 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
[email protected]9e54cb572010-09-03 20:08:065555 " \"external_crx\": \"RandomExtension.crx\","
5556 " \"external_version\": \"1.0\""
5557 " },"
5558 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5559 " \"external_crx\": \"RandomExtension2.crx\","
5560 " \"external_version\": \"2.0\""
5561 " },"
5562 " \"cccccccccccccccccccccccccccccccc\": {"
[email protected]d8fd0fd2014-03-24 13:16:065563 " \"external_update_url\": \"http:\\\\foo.com/update\","
5564 " \"install_parameter\": \"id\""
[email protected]9e54cb572010-09-03 20:08:065565 " }"
[email protected]27b985d2009-06-25 17:53:155566 "}";
[email protected]f0841cd2011-01-19 15:07:245567 EXPECT_EQ(3, visitor.Visit(json_data));
[email protected]27b985d2009-06-25 17:53:155568
[email protected]9e54cb572010-09-03 20:08:065569 // Simulate an external_extensions.json file that contains seven invalid
[email protected]f0841cd2011-01-19 15:07:245570 // records:
[email protected]27b985d2009-06-25 17:53:155571 // - One that is missing the 'external_crx' key.
5572 // - One that is missing the 'external_version' key.
5573 // - One that is specifying .. in the path.
[email protected]8ef78fd2010-08-19 17:14:325574 // - One that specifies both a file and update URL.
5575 // - One that specifies no file or update URL.
5576 // - One that has an update URL that is not well formed.
[email protected]9e54cb572010-09-03 20:08:065577 // - One that contains a malformed version.
[email protected]ab22ba42011-01-14 16:36:385578 // - One that has an invalid id.
5579 // - One that has a non-dictionary value.
[email protected]0d461c52012-07-03 19:29:415580 // - One that has an integer 'external_version' instead of a string.
[email protected]9e54cb572010-09-03 20:08:065581 // The final extension is valid, and we check that it is read to make sure
5582 // failures don't stop valid records from being read.
[email protected]27b985d2009-06-25 17:53:155583 json_data =
5584 "{"
[email protected]9e54cb572010-09-03 20:08:065585 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5586 " \"external_version\": \"1.0\""
5587 " },"
5588 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5589 " \"external_crx\": \"RandomExtension.crx\""
5590 " },"
5591 " \"cccccccccccccccccccccccccccccccc\": {"
5592 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
5593 " \"external_version\": \"2.0\""
5594 " },"
5595 " \"dddddddddddddddddddddddddddddddd\": {"
5596 " \"external_crx\": \"RandomExtension2.crx\","
5597 " \"external_version\": \"2.0\","
5598 " \"external_update_url\": \"http:\\\\foo.com/update\""
5599 " },"
5600 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
5601 " },"
5602 " \"ffffffffffffffffffffffffffffffff\": {"
5603 " \"external_update_url\": \"This string is not a valid URL\""
5604 " },"
5605 " \"gggggggggggggggggggggggggggggggg\": {"
5606 " \"external_crx\": \"RandomExtension3.crx\","
5607 " \"external_version\": \"This is not a valid version!\""
5608 " },"
[email protected]ab22ba42011-01-14 16:36:385609 " \"This is not a valid id!\": {},"
5610 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
[email protected]0d461c52012-07-03 19:29:415611 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
5612 " \"external_crx\": \"RandomExtension4.crx\","
5613 " \"external_version\": 1.0"
5614 " },"
[email protected]ab22ba42011-01-14 16:36:385615 " \"pppppppppppppppppppppppppppppppp\": {"
[email protected]9e54cb572010-09-03 20:08:065616 " \"external_crx\": \"RandomValidExtension.crx\","
5617 " \"external_version\": \"1.0\""
5618 " }"
[email protected]27b985d2009-06-25 17:53:155619 "}";
[email protected]683d0702010-12-06 16:25:575620 EXPECT_EQ(1, visitor.Visit(json_data));
[email protected]f0841cd2011-01-19 15:07:245621
5622 // Check that if a base path is not provided, use of a relative
5623 // path fails.
[email protected]650b2d52013-02-10 03:41:455624 base::FilePath empty;
[email protected]f0841cd2011-01-19 15:07:245625 MockProviderVisitor visitor_no_relative_paths(empty);
5626
5627 // Use absolute paths. Expect success.
5628 json_data =
5629 "{"
5630 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5631 " \"external_crx\": \"//RandomExtension1.crx\","
5632 " \"external_version\": \"3.0\""
5633 " },"
5634 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5635 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
5636 " \"external_version\": \"3.0\""
5637 " }"
5638 "}";
5639 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
5640
5641 // Use a relative path. Expect that it will error out.
5642 json_data =
5643 "{"
5644 " \"cccccccccccccccccccccccccccccccc\": {"
5645 " \"external_crx\": \"RandomExtension2.crx\","
5646 " \"external_version\": \"3.0\""
5647 " }"
5648 "}";
5649 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
[email protected]9d32ded072011-10-11 16:31:055650
5651 // Test supported_locales.
5652 json_data =
5653 "{"
5654 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5655 " \"external_crx\": \"RandomExtension.crx\","
5656 " \"external_version\": \"1.0\","
5657 " \"supported_locales\": [ \"en\" ]"
5658 " },"
5659 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5660 " \"external_crx\": \"RandomExtension2.crx\","
5661 " \"external_version\": \"2.0\","
5662 " \"supported_locales\": [ \"en-GB\" ]"
5663 " },"
5664 " \"cccccccccccccccccccccccccccccccc\": {"
5665 " \"external_crx\": \"RandomExtension2.crx\","
5666 " \"external_version\": \"3.0\","
5667 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
5668 " }"
5669 "}";
5670 {
5671 ScopedBrowserLocale guard("en-US");
5672 EXPECT_EQ(2, visitor.Visit(json_data));
5673 }
[email protected]f121003b2012-05-04 21:57:475674
[email protected]19eac6d2013-05-30 06:51:035675 // Test keep_if_present.
5676 json_data =
5677 "{"
5678 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5679 " \"external_crx\": \"RandomExtension.crx\","
5680 " \"external_version\": \"1.0\","
5681 " \"keep_if_present\": true"
5682 " }"
5683 "}";
5684 {
5685 EXPECT_EQ(0, visitor.Visit(json_data));
5686 }
5687
[email protected]f121003b2012-05-04 21:57:475688 // Test is_bookmark_app.
5689 MockProviderVisitor from_bookmark_visitor(
5690 base_path, Extension::FROM_BOOKMARK);
5691 json_data =
5692 "{"
5693 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5694 " \"external_crx\": \"RandomExtension.crx\","
5695 " \"external_version\": \"1.0\","
5696 " \"is_bookmark_app\": true"
5697 " }"
5698 "}";
5699 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
[email protected]7425d7df2012-11-28 14:35:425700
5701 // Test is_from_webstore.
5702 MockProviderVisitor from_webstore_visitor(
5703 base_path, Extension::FROM_WEBSTORE);
5704 json_data =
5705 "{"
5706 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5707 " \"external_crx\": \"RandomExtension.crx\","
5708 " \"external_version\": \"1.0\","
5709 " \"is_from_webstore\": true"
5710 " }"
5711 "}";
5712 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
[email protected]bf9fd5ae2014-04-09 22:50:065713
5714 // Test was_installed_by_eom.
5715 MockProviderVisitor was_installed_by_eom_visitor(
5716 base_path, Extension::WAS_INSTALLED_BY_OEM);
5717 json_data =
5718 "{"
5719 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5720 " \"external_crx\": \"RandomExtension.crx\","
5721 " \"external_version\": \"1.0\","
5722 " \"was_installed_by_oem\": true"
5723 " }"
5724 "}";
5725 EXPECT_EQ(1, was_installed_by_eom_visitor.Visit(json_data));
dpolukhin2c6ef2932015-05-12 16:06:135726
5727 // Test min_profile_created_by_version.
5728 MockProviderVisitor min_profile_created_by_version_visitor(base_path);
5729 json_data =
5730 "{"
5731 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5732 " \"external_crx\": \"RandomExtension.crx\","
5733 " \"external_version\": \"1.0\","
5734 " \"min_profile_created_by_version\": \"42.0.0.1\""
5735 " },"
5736 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5737 " \"external_crx\": \"RandomExtension2.crx\","
5738 " \"external_version\": \"1.0\","
5739 " \"min_profile_created_by_version\": \"43.0.0.1\""
5740 " },"
5741 " \"cccccccccccccccccccccccccccccccc\": {"
5742 " \"external_crx\": \"RandomExtension3.crx\","
5743 " \"external_version\": \"3.0\","
5744 " \"min_profile_created_by_version\": \"44.0.0.1\""
5745 " }"
5746 "}";
5747 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5748 prefs::kProfileCreatedByVersion, "40.0.0.1");
5749 EXPECT_EQ(0, min_profile_created_by_version_visitor.Visit(json_data));
5750 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5751 prefs::kProfileCreatedByVersion, "43.0.0.1");
5752 EXPECT_EQ(2, min_profile_created_by_version_visitor.Visit(json_data));
5753 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5754 prefs::kProfileCreatedByVersion, "45.0.0.1");
5755 EXPECT_EQ(3, min_profile_created_by_version_visitor.Visit(json_data));
[email protected]e18236b2009-06-22 21:32:105756}
[email protected]36a784c2009-06-23 06:21:085757
dpolukhin1687ef32015-06-22 11:12:375758TEST_F(ExtensionServiceTest, DoNotInstallForEnterprise) {
5759 InitializeEmptyExtensionService();
5760
5761 const base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5762 ASSERT_TRUE(base_path.IsAbsolute());
5763 MockProviderVisitor visitor(base_path);
5764 policy::ProfilePolicyConnector* const connector =
Xi Hanfe39afc62019-04-29 14:50:145765 visitor.profile()->GetProfilePolicyConnector();
dpolukhin1687ef32015-06-22 11:12:375766 connector->OverrideIsManagedForTesting(true);
5767 EXPECT_TRUE(connector->IsManaged());
5768
5769 std::string json_data =
5770 "{"
5771 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5772 " \"external_crx\": \"RandomExtension.crx\","
5773 " \"external_version\": \"1.0\","
5774 " \"do_not_install_for_enterprise\": true"
5775 " },"
5776 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5777 " \"external_crx\": \"RandomExtension2.crx\","
5778 " \"external_version\": \"1.0\""
5779 " }"
5780 "}";
5781 EXPECT_EQ(1, visitor.Visit(json_data));
5782}
5783
lazyboye8634172016-01-28 00:10:485784TEST_F(ExtensionServiceTest, IncrementalUpdateThroughRegistry) {
5785 InitializeEmptyExtensionService();
5786
5787 // Test some valid extension records.
5788 // Set a base path to avoid erroring out on relative paths.
5789 // Paths starting with // are absolute on every platform we support.
5790 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5791 ASSERT_TRUE(base_path.IsAbsolute());
5792 MockUpdateProviderVisitor visitor(base_path);
5793 std::string json_data =
5794 "{"
5795 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5796 " \"external_crx\": \"RandomExtension.crx\","
5797 " \"external_version\": \"1.0\""
5798 " },"
5799 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5800 " \"external_crx\": \"RandomExtension2.crx\","
5801 " \"external_version\": \"2.0\""
5802 " },"
5803 " \"cccccccccccccccccccccccccccccccc\": {"
5804 " \"external_update_url\": \"http:\\\\foo.com/update\","
5805 " \"install_parameter\": \"id\""
5806 " }"
5807 "}";
5808 EXPECT_EQ(3, visitor.Visit(json_data, Manifest::EXTERNAL_REGISTRY,
5809 Manifest::EXTERNAL_PREF_DOWNLOAD));
5810
5811 // c* removed and d*, e*, f* added, a*, b* existing.
5812 json_data =
5813 "{"
5814 " \"dddddddddddddddddddddddddddddddd\": {"
5815 " \"external_crx\": \"RandomExtension3.crx\","
5816 " \"external_version\": \"1.0\""
5817 " },"
5818 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
5819 " \"external_update_url\": \"http:\\\\foo.com/update\","
5820 " \"install_parameter\": \"id\""
5821 " },"
5822 " \"ffffffffffffffffffffffffffffffff\": {"
5823 " \"external_update_url\": \"http:\\\\bar.com/update\","
5824 " \"install_parameter\": \"id\""
5825 " },"
5826 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5827 " \"external_crx\": \"RandomExtension.crx\","
5828 " \"external_version\": \"1.0\""
5829 " },"
5830 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5831 " \"external_crx\": \"RandomExtension2.crx\","
5832 " \"external_version\": \"2.0\""
5833 " }"
5834 "}";
5835
5836 // This will simulate registry loader observing new changes in registry and
5837 // hence will discover new extensions.
5838 visitor.VisitDueToUpdate(json_data);
5839
5840 // UpdateUrl.
5841 EXPECT_EQ(2u, visitor.GetUpdateURLExtensionCount());
5842 EXPECT_TRUE(
5843 visitor.HasSeenUpdateWithUpdateUrl("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"));
5844 EXPECT_TRUE(
5845 visitor.HasSeenUpdateWithUpdateUrl("ffffffffffffffffffffffffffffffff"));
5846
5847 // File.
5848 EXPECT_EQ(3u, visitor.GetFileExtensionCount());
5849 EXPECT_TRUE(
5850 visitor.HasSeenUpdateWithFile("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
5851 EXPECT_TRUE(
5852 visitor.HasSeenUpdateWithFile("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
5853 EXPECT_TRUE(
5854 visitor.HasSeenUpdateWithFile("dddddddddddddddddddddddddddddddd"));
5855
5856 // Removed extensions.
5857 EXPECT_EQ(1u, visitor.GetRemovedExtensionCount());
5858 EXPECT_TRUE(visitor.HasSeenRemoval("cccccccccccccccccccccccccccccccc"));
5859
5860 // Simulate all 5 extensions being removed.
5861 json_data = "{}";
5862 visitor.VisitDueToUpdate(json_data);
5863 EXPECT_EQ(0u, visitor.GetUpdateURLExtensionCount());
5864 EXPECT_EQ(0u, visitor.GetFileExtensionCount());
5865 EXPECT_EQ(5u, visitor.GetRemovedExtensionCount());
5866}
5867
[email protected]c6d474f82009-12-16 21:11:065868// Test loading good extensions from the profile directory.
[email protected]d9a61e12012-11-14 02:43:475869TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
[email protected]6884a802012-08-07 03:55:225870 // Ensure we're testing in "en" and leave global state untouched.
5871 extension_l10n_util::ScopedLocaleForTest testLocale("en");
5872
[email protected]c6d474f82009-12-16 21:11:065873 // Initialize the test dir with a good Preferences/extensions.
[email protected]f484f8d52014-06-12 08:38:185874 base::FilePath source_install_dir = data_dir().AppendASCII("l10n");
[email protected]e96a0602014-02-15 08:27:425875 base::FilePath pref_path =
5876 source_install_dir.Append(chrome::kPreferencesFilename);
[email protected]eaa7dd182010-12-14 11:09:005877 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]c6d474f82009-12-16 21:11:065878
[email protected]f484f8d52014-06-12 08:38:185879 service()->Init();
[email protected]c6d474f82009-12-16 21:11:065880
5881 ASSERT_EQ(3u, loaded_.size());
5882
5883 // This was equal to "sr" on load.
5884 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
5885
5886 // These are untouched by re-localization.
5887 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
5888 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
5889
5890 // This one starts with Serbian name, and gets re-localized into English.
5891 EXPECT_EQ("My name is simple.", loaded_[0]->name());
5892
5893 // These are untouched by re-localization.
5894 EXPECT_EQ("My name is simple.", loaded_[1]->name());
5895 EXPECT_EQ("no l10n", loaded_[2]->name());
5896}
5897
[email protected]6c2381d2011-10-19 02:52:535898class ExtensionsReadyRecorder : public content::NotificationObserver {
[email protected]f0488f2f2009-07-01 05:25:225899 public:
5900 ExtensionsReadyRecorder() : ready_(false) {
Devlin Cronineea1b7a2018-05-26 02:46:215901 registrar_.Add(this, NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
[email protected]ad50def52011-10-19 23:17:075902 content::NotificationService::AllSources());
[email protected]f0488f2f2009-07-01 05:25:225903 }
5904
5905 void set_ready(bool value) { ready_ = value; }
5906 bool ready() { return ready_; }
5907
5908 private:
dchengae36a4a2014-10-21 12:36:365909 void Observe(int type,
5910 const content::NotificationSource& source,
5911 const content::NotificationDetails& details) override {
[email protected]432115822011-07-10 15:52:275912 switch (type) {
Devlin Cronineea1b7a2018-05-26 02:46:215913 case NOTIFICATION_EXTENSIONS_READY_DEPRECATED:
[email protected]f0488f2f2009-07-01 05:25:225914 ready_ = true;
5915 break;
5916 default:
5917 NOTREACHED();
5918 }
5919 }
5920
[email protected]6c2381d2011-10-19 02:52:535921 content::NotificationRegistrar registrar_;
[email protected]f0488f2f2009-07-01 05:25:225922 bool ready_;
5923};
5924
[email protected]36a784c2009-06-23 06:21:085925// Test that we get enabled/disabled correctly for all the pref/command-line
[email protected]eaa7dd182010-12-14 11:09:005926// combinations. We don't want to derive from the ExtensionServiceTest class
5927// for this test, so we use ExtensionServiceTestSimple.
[email protected]f0488f2f2009-07-01 05:25:225928//
5929// Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5930// enabled or not.
skyostil0becb332015-04-27 17:59:375931class ExtensionServiceTestSimple : public testing::Test {
Gabriel Charette798fde72019-08-20 22:24:045932 content::BrowserTaskEnvironment task_environment_;
skyostil0becb332015-04-27 17:59:375933};
5934
5935TEST_F(ExtensionServiceTestSimple, Enabledness) {
[email protected]5a24d2b2012-11-14 20:38:315936 // Make sure the PluginService singleton is destroyed at the end of the test.
[email protected]39fdf5202012-11-14 00:38:175937 base::ShadowingAtExitManager at_exit_manager;
brettw4b461082016-11-19 18:55:165938#if BUILDFLAG(ENABLE_PLUGINS)
[email protected]8f3372122013-07-18 04:34:145939 content::PluginService::GetInstance()->Init();
[email protected]8f3372122013-07-18 04:34:145940#endif
[email protected]5a24d2b2012-11-14 20:38:315941
Devlin Cronineea1b7a2018-05-26 02:46:215942 LoadErrorReporter::Init(false); // no noisy errors
[email protected]f0488f2f2009-07-01 05:25:225943 ExtensionsReadyRecorder recorder;
Alexey Baskakov7ae8ccc2019-02-11 02:26:075944
dchengc963c7142016-04-08 03:55:225945 std::unique_ptr<base::CommandLine> command_line;
[email protected]be5a6db2012-11-13 14:39:115946
Alexey Baskakov7ae8ccc2019-02-11 02:26:075947 // The profile lifetimes must not overlap: services may use global variables.
5948 {
5949 auto profile = std::make_unique<TestingProfile>();
5950 base::FilePath install_dir =
5951 profile->GetPath().AppendASCII(kInstallDirectoryName);
[email protected]6d60703b2009-08-29 01:29:235952
Alexey Baskakov7ae8ccc2019-02-11 02:26:075953 // By default, we are enabled.
5954 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5955 ExtensionService* service =
5956 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile.get()))
5957 ->CreateExtensionService(command_line.get(), install_dir, false);
5958 EXPECT_TRUE(service->extensions_enabled());
5959 service->Init();
5960 content::RunAllTasksUntilIdle();
5961 EXPECT_TRUE(recorder.ready());
5962 }
[email protected]36a784c2009-06-23 06:21:085963
Alexey Baskakov7ae8ccc2019-02-11 02:26:075964 {
5965 // If either the command line or pref is set, we are disabled.
5966 recorder.set_ready(false);
5967 auto profile = std::make_unique<TestingProfile>();
5968 base::FilePath install_dir =
5969 profile->GetPath().AppendASCII(kInstallDirectoryName);
5970 command_line->AppendSwitch(::switches::kDisableExtensions);
5971 ExtensionService* service =
5972 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile.get()))
5973 ->CreateExtensionService(command_line.get(), install_dir, false);
5974 EXPECT_FALSE(service->extensions_enabled());
5975 service->Init();
5976 content::RunAllTasksUntilIdle();
5977 EXPECT_TRUE(recorder.ready());
5978 }
[email protected]36a784c2009-06-23 06:21:085979
Alexey Baskakov7ae8ccc2019-02-11 02:26:075980 {
5981 recorder.set_ready(false);
5982 auto profile = std::make_unique<TestingProfile>();
5983 base::FilePath install_dir =
5984 profile->GetPath().AppendASCII(kInstallDirectoryName);
5985 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5986 ExtensionService* service =
5987 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile.get()))
5988 ->CreateExtensionService(command_line.get(), install_dir, false);
5989 EXPECT_FALSE(service->extensions_enabled());
5990 service->Init();
5991 content::RunAllTasksUntilIdle();
5992 EXPECT_TRUE(recorder.ready());
5993 }
[email protected]7e1951a2010-09-30 10:22:205994
Alexey Baskakov7ae8ccc2019-02-11 02:26:075995 {
5996 recorder.set_ready(false);
5997 auto profile = std::make_unique<TestingProfile>();
5998 base::FilePath install_dir =
5999 profile->GetPath().AppendASCII(kInstallDirectoryName);
6000 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
6001 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
6002 ExtensionService* service =
6003 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile.get()))
6004 ->CreateExtensionService(command_line.get(), install_dir, false);
6005 EXPECT_FALSE(service->extensions_enabled());
6006 service->Init();
6007 content::RunAllTasksUntilIdle();
6008 EXPECT_TRUE(recorder.ready());
6009 }
6010
[email protected]060d4972012-07-19 17:22:396011 // Execute any pending deletion tasks.
Gabriel Charette01507a22017-09-27 21:30:086012 content::RunAllTasksUntilIdle();
[email protected]36a784c2009-06-23 06:21:086013}
[email protected]24b538a2010-02-27 01:22:446014
6015// Test loading extensions that require limited and unlimited storage quotas.
[email protected]d9a61e12012-11-14 02:43:476016TEST_F(ExtensionServiceTest, StorageQuota) {
[email protected]eaa7dd182010-12-14 11:09:006017 InitializeEmptyExtensionService();
[email protected]24b538a2010-02-27 01:22:446018
[email protected]f484f8d52014-06-12 08:38:186019 base::FilePath extensions_path = data_dir().AppendASCII("storage_quota");
[email protected]24b538a2010-02-27 01:22:446020
[email protected]650b2d52013-02-10 03:41:456021 base::FilePath limited_quota_ext =
[email protected]e85e34c32011-04-13 18:38:356022 extensions_path.AppendASCII("limited_quota")
[email protected]24b538a2010-02-27 01:22:446023 .AppendASCII("1.0");
[email protected]03b612f2010-08-13 21:09:216024
6025 // The old permission name for unlimited quota was "unlimited_storage", but
6026 // we changed it to "unlimitedStorage". This tests both versions.
[email protected]650b2d52013-02-10 03:41:456027 base::FilePath unlimited_quota_ext =
[email protected]e85e34c32011-04-13 18:38:356028 extensions_path.AppendASCII("unlimited_quota")
[email protected]24b538a2010-02-27 01:22:446029 .AppendASCII("1.0");
[email protected]650b2d52013-02-10 03:41:456030 base::FilePath unlimited_quota_ext2 =
[email protected]e85e34c32011-04-13 18:38:356031 extensions_path.AppendASCII("unlimited_quota")
[email protected]03b612f2010-08-13 21:09:216032 .AppendASCII("2.0");
Devlin Cronineea1b7a2018-05-26 02:46:216033 UnpackedInstaller::Create(service())->Load(limited_quota_ext);
6034 UnpackedInstaller::Create(service())->Load(unlimited_quota_ext);
6035 UnpackedInstaller::Create(service())->Load(unlimited_quota_ext2);
Gabriel Charette01507a22017-09-27 21:30:086036 content::RunAllTasksUntilIdle();
[email protected]24b538a2010-02-27 01:22:446037
[email protected]03b612f2010-08-13 21:09:216038 ASSERT_EQ(3u, loaded_.size());
[email protected]f484f8d52014-06-12 08:38:186039 EXPECT_TRUE(profile());
6040 EXPECT_FALSE(profile()->IsOffTheRecord());
6041 EXPECT_FALSE(
6042 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
6043 loaded_[0]->url()));
6044 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
[email protected]7c5f2ec2011-05-26 19:15:266045 loaded_[1]->url()));
[email protected]f484f8d52014-06-12 08:38:186046 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
[email protected]7c5f2ec2011-05-26 19:15:266047 loaded_[2]->url()));
[email protected]24b538a2010-02-27 01:22:446048}
[email protected]1952c7d2010-03-04 23:48:346049
[email protected]d8c8f25f2011-11-02 18:18:016050// Tests ComponentLoader::Add().
[email protected]d9a61e12012-11-14 02:43:476051TEST_F(ExtensionServiceTest, ComponentExtensions) {
[email protected]f0b97f12010-10-11 21:44:356052 // Component extensions should work even when extensions are disabled.
rdevlin.cronin7217be52017-03-24 20:47:056053 InitializeExtensionServiceWithExtensionsDisabled();
[email protected]f0b97f12010-10-11 21:44:356054
[email protected]f484f8d52014-06-12 08:38:186055 base::FilePath path = data_dir()
6056 .AppendASCII("good")
6057 .AppendASCII("Extensions")
6058 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
6059 .AppendASCII("1.0.0.0");
[email protected]1952c7d2010-03-04 23:48:346060
6061 std::string manifest;
Devlin Cronineea1b7a2018-05-26 02:46:216062 ASSERT_TRUE(
6063 base::ReadFileToString(path.Append(kManifestFilename), &manifest));
[email protected]1952c7d2010-03-04 23:48:346064
[email protected]f484f8d52014-06-12 08:38:186065 service()->component_loader()->Add(manifest, path);
6066 service()->Init();
[email protected]1952c7d2010-03-04 23:48:346067
6068 // Note that we do not pump messages -- the extension should be loaded
6069 // immediately.
6070
6071 EXPECT_EQ(0u, GetErrors().size());
6072 ASSERT_EQ(1u, loaded_.size());
[email protected]1d5e58b2013-01-31 08:41:406073 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
[email protected]f484f8d52014-06-12 08:38:186074 EXPECT_EQ(1u, registry()->enabled_extensions().size());
[email protected]1952c7d2010-03-04 23:48:346075
[email protected]8c484b742012-11-29 06:05:366076 // Component extensions get a prefs entry on first install.
6077 ValidatePrefKeyCount(1);
[email protected]1952c7d2010-03-04 23:48:346078
6079 // Reload all extensions, and make sure it comes back.
[email protected]f484f8d52014-06-12 08:38:186080 std::string extension_id = (*registry()->enabled_extensions().begin())->id();
[email protected]1952c7d2010-03-04 23:48:346081 loaded_.clear();
[email protected]f484f8d52014-06-12 08:38:186082 service()->ReloadExtensionsForTest();
6083 ASSERT_EQ(1u, registry()->enabled_extensions().size());
6084 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id());
[email protected]1952c7d2010-03-04 23:48:346085}
[email protected]145a317b2011-04-12 16:03:466086
[email protected]d9a61e12012-11-14 02:43:476087TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
[email protected]8a87a5332011-08-11 17:54:596088 InitializeEmptyExtensionService();
6089
[email protected]f484f8d52014-06-12 08:38:186090 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:506091 InstallCRX(path, INSTALL_NEW);
[email protected]8a87a5332011-08-11 17:54:596092 ValidatePrefKeyCount(1u);
6093 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:406094 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
[email protected]8a87a5332011-08-11 17:54:596095
Devlin Cronineea1b7a2018-05-26 02:46:216096 PendingExtensionManager* pending = service()->pending_extension_manager();
[email protected]8a87a5332011-08-11 17:54:596097 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6098
6099 // Skip install when the location is the same.
Devlin Cronind4c2a8f32017-09-29 17:08:306100 GURL good_update_url(kGoodUpdateURL);
Devlin Cronin92c52cac2017-10-02 21:29:016101 ExternalInstallInfoUpdateUrl info(
6102 kGoodId, std::string(), std::move(good_update_url), Manifest::INTERNAL,
6103 Extension::NO_FLAGS, false);
6104 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(info, true));
[email protected]8a87a5332011-08-11 17:54:596105 EXPECT_FALSE(pending->IsIdPending(kGoodId));
[email protected]9060d8b02012-01-13 02:14:306106
6107 // Install when the location has higher priority.
Devlin Cronin92c52cac2017-10-02 21:29:016108 info.download_location = Manifest::EXTERNAL_POLICY_DOWNLOAD;
6109 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(info, true));
[email protected]8a87a5332011-08-11 17:54:596110 EXPECT_TRUE(pending->IsIdPending(kGoodId));
[email protected]9060d8b02012-01-13 02:14:306111
6112 // Try the low priority again. Should be rejected.
Devlin Cronin92c52cac2017-10-02 21:29:016113 info.download_location = Manifest::EXTERNAL_PREF_DOWNLOAD;
6114 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(info, true));
[email protected]9060d8b02012-01-13 02:14:306115 // The existing record should still be present in the pending extension
6116 // manager.
6117 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6118
[email protected]8a87a5332011-08-11 17:54:596119 pending->Remove(kGoodId);
[email protected]9060d8b02012-01-13 02:14:306120
6121 // Skip install when the location has the same priority as the installed
6122 // location.
Devlin Cronin92c52cac2017-10-02 21:29:016123 info.download_location = Manifest::INTERNAL;
6124 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(info, true));
[email protected]9060d8b02012-01-13 02:14:306125
[email protected]8a87a5332011-08-11 17:54:596126 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6127}
6128
[email protected]d9a61e12012-11-14 02:43:476129TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
pwnallcbd73192016-08-22 18:59:176130 base::Version older_version("0.1.0.0");
6131 base::Version newer_version("2.0.0.0");
[email protected]9060d8b02012-01-13 02:14:306132
6133 // We don't want the extension to be installed. A path that doesn't
6134 // point to a valid CRX ensures this.
ginkage553af3202015-02-04 12:39:096135 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
[email protected]9060d8b02012-01-13 02:14:306136
6137 const int kCreationFlags = 0;
6138 const bool kDontMarkAcknowledged = false;
xiyuan4d82f7b62015-03-04 02:29:226139 const bool kDontInstallImmediately = false;
[email protected]9060d8b02012-01-13 02:14:306140
6141 InitializeEmptyExtensionService();
6142
6143 // The test below uses install source constants to test that
6144 // priority is enforced. It assumes a specific ranking of install
6145 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
6146 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
6147 // The following assertions verify these assumptions:
[email protected]1d5e58b2013-01-31 08:41:406148 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6149 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6150 Manifest::EXTERNAL_PREF));
6151 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6152 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6153 Manifest::INTERNAL));
6154 ASSERT_EQ(Manifest::EXTERNAL_PREF,
6155 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
6156 Manifest::INTERNAL));
[email protected]9060d8b02012-01-13 02:14:306157
Devlin Cronineea1b7a2018-05-26 02:46:216158 PendingExtensionManager* pending = service()->pending_extension_manager();
[email protected]9060d8b02012-01-13 02:14:306159 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6160
Devlin Cronin92c52cac2017-10-02 21:29:016161 ExternalInstallInfoFile info(kGoodId, older_version, kInvalidPathToCrx,
6162 Manifest::INTERNAL, kCreationFlags,
6163 kDontMarkAcknowledged, kDontInstallImmediately);
[email protected]97d6a5c2013-11-11 23:51:246164 {
6165 // Simulate an external source adding the extension as INTERNAL.
6166 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:216167 NOTIFICATION_CRX_INSTALLER_DONE,
[email protected]97d6a5c2013-11-11 23:51:246168 content::NotificationService::AllSources());
Devlin Cronin92c52cac2017-10-02 21:29:016169 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
[email protected]97d6a5c2013-11-11 23:51:246170 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6171 observer.Wait();
6172 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6173 }
[email protected]9060d8b02012-01-13 02:14:306174
[email protected]97d6a5c2013-11-11 23:51:246175 {
6176 // Simulate an external source adding the extension as EXTERNAL_PREF.
6177 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:216178 NOTIFICATION_CRX_INSTALLER_DONE,
[email protected]97d6a5c2013-11-11 23:51:246179 content::NotificationService::AllSources());
Devlin Cronin92c52cac2017-10-02 21:29:016180 info.crx_location = Manifest::EXTERNAL_PREF;
6181 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
[email protected]97d6a5c2013-11-11 23:51:246182 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6183 observer.Wait();
6184 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6185 }
[email protected]9060d8b02012-01-13 02:14:306186
6187 // Simulate an external source adding as EXTERNAL_PREF again.
[email protected]4ec0f4b2012-12-07 09:41:466188 // This is rejected because the version and the location are the same as
6189 // the previous installation, which is still pending.
Devlin Cronin92c52cac2017-10-02 21:29:016190 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306191 EXPECT_TRUE(pending->IsIdPending(kGoodId));
[email protected]9060d8b02012-01-13 02:14:306192
6193 // Try INTERNAL again. Should fail.
Devlin Cronin92c52cac2017-10-02 21:29:016194 info.crx_location = Manifest::INTERNAL;
6195 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306196 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6197
[email protected]97d6a5c2013-11-11 23:51:246198 {
6199 // Now the registry adds the extension.
6200 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:216201 NOTIFICATION_CRX_INSTALLER_DONE,
[email protected]97d6a5c2013-11-11 23:51:246202 content::NotificationService::AllSources());
Devlin Cronin92c52cac2017-10-02 21:29:016203 info.crx_location = Manifest::EXTERNAL_REGISTRY;
6204 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
[email protected]97d6a5c2013-11-11 23:51:246205 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6206 observer.Wait();
6207 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6208 }
[email protected]9060d8b02012-01-13 02:14:306209
6210 // Registry outranks both external pref and internal, so both fail.
Devlin Cronin92c52cac2017-10-02 21:29:016211 info.crx_location = Manifest::EXTERNAL_PREF;
6212 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306213 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6214
Devlin Cronin92c52cac2017-10-02 21:29:016215 info.crx_location = Manifest::INTERNAL;
6216 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306217 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6218
6219 pending->Remove(kGoodId);
6220
6221 // Install the extension.
[email protected]f484f8d52014-06-12 08:38:186222 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]9060d8b02012-01-13 02:14:306223 const Extension* ext = InstallCRX(path, INSTALL_NEW);
6224 ValidatePrefKeyCount(1u);
6225 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
[email protected]1d5e58b2013-01-31 08:41:406226 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
[email protected]9060d8b02012-01-13 02:14:306227
6228 // Now test the logic of OnExternalExtensionFileFound() when the extension
6229 // being added is already installed.
6230
6231 // Tests assume |older_version| is less than the installed version, and
6232 // |newer_version| is greater. Verify this:
Devlin Cronin03bf2d22017-12-20 08:21:056233 ASSERT_LT(older_version, ext->version());
6234 ASSERT_GT(newer_version, ext->version());
[email protected]9060d8b02012-01-13 02:14:306235
6236 // An external install for the same location should fail if the version is
6237 // older, or the same, and succeed if the version is newer.
6238
6239 // Older than the installed version...
Devlin Cronin92c52cac2017-10-02 21:29:016240 info.version = older_version;
6241 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306242 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6243
6244 // Same version as the installed version...
Devlin Cronin03bf2d22017-12-20 08:21:056245 info.version = ext->version();
Devlin Cronin92c52cac2017-10-02 21:29:016246 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306247 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6248
6249 // Newer than the installed version...
Devlin Cronin92c52cac2017-10-02 21:29:016250 info.version = newer_version;
6251 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306252 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6253
6254 // An external install for a higher priority install source should succeed
6255 // if the version is greater. |older_version| is not...
Devlin Cronin92c52cac2017-10-02 21:29:016256 info.version = older_version;
6257 info.crx_location = Manifest::EXTERNAL_PREF;
6258 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306259 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6260
6261 // |newer_version| is newer.
Devlin Cronin92c52cac2017-10-02 21:29:016262 info.version = newer_version;
6263 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306264 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6265
6266 // An external install for an even higher priority install source should
6267 // succeed if the version is greater.
Devlin Cronin92c52cac2017-10-02 21:29:016268 info.crx_location = Manifest::EXTERNAL_REGISTRY;
6269 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306270 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6271
6272 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
6273 // adding from external pref will now fail.
Devlin Cronin92c52cac2017-10-02 21:29:016274 info.crx_location = Manifest::EXTERNAL_PREF;
6275 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
[email protected]9060d8b02012-01-13 02:14:306276 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6277}
6278
[email protected]d9a61e12012-11-14 02:43:476279TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
pwnallcbd73192016-08-22 18:59:176280 base::Version kVersion123("1.2.3");
6281 base::Version kVersion124("1.2.4");
6282 base::Version kVersion125("1.2.5");
ginkage553af3202015-02-04 12:39:096283 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
[email protected]e3987852012-05-04 10:06:306284 const int kCreationFlags = 0;
6285 const bool kDontMarkAcknowledged = false;
xiyuan4d82f7b62015-03-04 02:29:226286 const bool kDontInstallImmediately = false;
[email protected]e3987852012-05-04 10:06:306287
6288 InitializeEmptyExtensionService();
6289
Devlin Cronineea1b7a2018-05-26 02:46:216290 PendingExtensionManager* pending = service()->pending_extension_manager();
[email protected]e3987852012-05-04 10:06:306291 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6292
6293 // An external provider starts installing from a local crx.
Devlin Cronin92c52cac2017-10-02 21:29:016294 ExternalInstallInfoFile info(kGoodId, kVersion123, kInvalidPathToCrx,
6295 Manifest::EXTERNAL_PREF, kCreationFlags,
6296 kDontMarkAcknowledged, kDontInstallImmediately);
6297 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
lazyboye8634172016-01-28 00:10:486298
Devlin Cronineea1b7a2018-05-26 02:46:216299 const PendingExtensionInfo* pending_info;
lazyboye8634172016-01-28 00:10:486300 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6301 EXPECT_TRUE(pending_info->version().IsValid());
6302 EXPECT_EQ(pending_info->version(), kVersion123);
[email protected]e3987852012-05-04 10:06:306303
6304 // Adding a newer version overrides the currently pending version.
Devlin Cronin92c52cac2017-10-02 21:29:016305 info.version = base::Version(kVersion124);
6306 EXPECT_TRUE(service()->OnExternalExtensionFileFound(info));
lazyboye8634172016-01-28 00:10:486307 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6308 EXPECT_TRUE(pending_info->version().IsValid());
6309 EXPECT_EQ(pending_info->version(), kVersion124);
[email protected]e3987852012-05-04 10:06:306310
6311 // Adding an older version fails.
Devlin Cronin92c52cac2017-10-02 21:29:016312 info.version = kVersion123;
6313 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
lazyboye8634172016-01-28 00:10:486314 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6315 EXPECT_TRUE(pending_info->version().IsValid());
6316 EXPECT_EQ(pending_info->version(), kVersion124);
[email protected]e3987852012-05-04 10:06:306317
6318 // Adding an older version fails even when coming from a higher-priority
6319 // location.
Devlin Cronin92c52cac2017-10-02 21:29:016320 info.crx_location = Manifest::EXTERNAL_REGISTRY;
6321 EXPECT_FALSE(service()->OnExternalExtensionFileFound(info));
lazyboye8634172016-01-28 00:10:486322 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6323 EXPECT_TRUE(pending_info->version().IsValid());
6324 EXPECT_EQ(pending_info->version(), kVersion124);
[email protected]e3987852012-05-04 10:06:306325
6326 // Adding the latest version from the webstore overrides a specific version.
Devlin Cronin92c52cac2017-10-02 21:29:016327 GURL kUpdateUrl("http://example.com/update");
6328 ExternalInstallInfoUpdateUrl update_info(kGoodId, std::string(), kUpdateUrl,
6329 Manifest::EXTERNAL_POLICY_DOWNLOAD,
6330 Extension::NO_FLAGS, false);
6331 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(update_info, true));
lazyboye8634172016-01-28 00:10:486332 EXPECT_TRUE((pending_info = pending->GetById(kGoodId)));
6333 EXPECT_FALSE(pending_info->version().IsValid());
[email protected]e3987852012-05-04 10:06:306334}
6335
[email protected]f5bf1842012-02-15 02:52:266336// This makes sure we can package and install CRX files that use whitelisted
6337// permissions.
[email protected]d9a61e12012-11-14 02:43:476338TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
[email protected]f5bf1842012-02-15 02:52:266339 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
avi3ef9ec9e2014-12-22 22:50:176340 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
Devlin Cronineea1b7a2018-05-26 02:46:216341 switches::kWhitelistedExtensionID, test_id);
[email protected]f5bf1842012-02-15 02:52:266342
6343 InitializeEmptyExtensionService();
[email protected]f484f8d52014-06-12 08:38:186344 base::FilePath path = data_dir().AppendASCII("permissions");
[email protected]650b2d52013-02-10 03:41:456345 base::FilePath pem_path = path
[email protected]f5bf1842012-02-15 02:52:266346 .AppendASCII("whitelist.pem");
6347 path = path
6348 .AppendASCII("whitelist");
6349
6350 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
6351 EXPECT_EQ(0u, GetErrors().size());
[email protected]f484f8d52014-06-12 08:38:186352 ASSERT_EQ(1u, registry()->enabled_extensions().size());
[email protected]f5bf1842012-02-15 02:52:266353 EXPECT_EQ(test_id, extension->id());
6354}
6355
[email protected]145a317b2011-04-12 16:03:466356// Test that when multiple sources try to install an extension,
6357// we consistently choose the right one. To make tests easy to read,
6358// methods that fake requests to install crx files in several ways
6359// are provided.
6360class ExtensionSourcePriorityTest : public ExtensionServiceTest {
6361 public:
dcheng72191812014-10-28 20:49:566362 void SetUp() override {
[email protected]ed8ee722011-04-22 06:49:446363 ExtensionServiceTest::SetUp();
6364
[email protected]145a317b2011-04-12 16:03:466365 // All tests use a single extension. Put the id and path in member vars
6366 // that all methods can read.
6367 crx_id_ = kGoodId;
[email protected]f484f8d52014-06-12 08:38:186368 crx_path_ = data_dir().AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:466369 }
6370
6371 // Fake an external source adding a URL to fetch an extension from.
[email protected]9060d8b02012-01-13 02:14:306372 bool AddPendingExternalPrefUrl() {
[email protected]f484f8d52014-06-12 08:38:186373 return service()->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]d8fd0fd2014-03-24 13:16:066374 crx_id_,
6375 std::string(),
6376 GURL(),
6377 Manifest::EXTERNAL_PREF_DOWNLOAD,
6378 Extension::NO_FLAGS,
6379 false);
[email protected]145a317b2011-04-12 16:03:466380 }
6381
6382 // Fake an external file from external_extensions.json.
[email protected]9060d8b02012-01-13 02:14:306383 bool AddPendingExternalPrefFileInstall() {
Devlin Cronin92c52cac2017-10-02 21:29:016384 ExternalInstallInfoFile info(crx_id_, base::Version("1.0.0.0"), crx_path_,
6385 Manifest::EXTERNAL_PREF, Extension::NO_FLAGS,
6386 false, false);
6387 return service()->OnExternalExtensionFileFound(info);
[email protected]145a317b2011-04-12 16:03:466388 }
6389
6390 // Fake a request from sync to install an extension.
6391 bool AddPendingSyncInstall() {
[email protected]f484f8d52014-06-12 08:38:186392 return service()->pending_extension_manager()->AddFromSync(
[email protected]21db9ef2014-05-16 02:06:276393 crx_id_,
6394 GURL(kGoodUpdateURL),
treibe960e282015-09-11 10:38:086395 base::Version(),
[email protected]21db9ef2014-05-16 02:06:276396 &IsExtension,
mamir192d7882016-06-22 17:10:166397 kGoodRemoteInstall);
[email protected]145a317b2011-04-12 16:03:466398 }
6399
[email protected]145a317b2011-04-12 16:03:466400 // Fake a policy install.
[email protected]9060d8b02012-01-13 02:14:306401 bool AddPendingPolicyInstall() {
[email protected]145a317b2011-04-12 16:03:466402 // Get path to the CRX with id |kGoodId|.
Devlin Cronin92c52cac2017-10-02 21:29:016403 ExternalInstallInfoUpdateUrl info(crx_id_, std::string(), GURL(),
6404 Manifest::EXTERNAL_POLICY_DOWNLOAD,
6405 Extension::NO_FLAGS, false);
6406 return service()->OnExternalExtensionUpdateUrlFound(info, true);
[email protected]145a317b2011-04-12 16:03:466407 }
6408
6409 // Get the install source of a pending extension.
[email protected]1d5e58b2013-01-31 08:41:406410 Manifest::Location GetPendingLocation() {
Devlin Cronineea1b7a2018-05-26 02:46:216411 const PendingExtensionInfo* info;
[email protected]f484f8d52014-06-12 08:38:186412 EXPECT_TRUE(
6413 (info = service()->pending_extension_manager()->GetById(crx_id_)));
[email protected]51a3bf8b2012-06-08 22:53:066414 return info->install_source();
[email protected]145a317b2011-04-12 16:03:466415 }
6416
6417 // Is an extension pending from a sync request?
6418 bool GetPendingIsFromSync() {
Devlin Cronineea1b7a2018-05-26 02:46:216419 const PendingExtensionInfo* info;
[email protected]f484f8d52014-06-12 08:38:186420 EXPECT_TRUE(
6421 (info = service()->pending_extension_manager()->GetById(crx_id_)));
[email protected]51a3bf8b2012-06-08 22:53:066422 return info->is_from_sync();
[email protected]145a317b2011-04-12 16:03:466423 }
6424
6425 // Is the CRX id these tests use pending?
6426 bool IsCrxPending() {
[email protected]f484f8d52014-06-12 08:38:186427 return service()->pending_extension_manager()->IsIdPending(crx_id_);
[email protected]145a317b2011-04-12 16:03:466428 }
6429
6430 // Is an extension installed?
6431 bool IsCrxInstalled() {
David Bertoni58c113a2019-08-02 19:53:266432 return (registry()->GetExtensionById(
6433 crx_id_, ExtensionRegistry::COMPATIBILITY) != nullptr);
[email protected]145a317b2011-04-12 16:03:466434 }
6435
6436 protected:
6437 // All tests use a single extension. Making the id and path member
6438 // vars avoids pasing the same argument to every method.
6439 std::string crx_id_;
[email protected]650b2d52013-02-10 03:41:456440 base::FilePath crx_path_;
[email protected]145a317b2011-04-12 16:03:466441};
6442
[email protected]3634ebd2011-04-20 00:34:126443// Test that a pending request for installation of an external CRX from
6444// an update URL overrides a pending request to install the same extension
6445// from sync.
[email protected]ed8ee722011-04-22 06:49:446446TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
[email protected]145a317b2011-04-12 16:03:466447 InitializeEmptyExtensionService();
6448
6449 ASSERT_FALSE(IsCrxInstalled());
6450
6451 // Install pending extension from sync.
[email protected]97d6a5c2013-11-11 23:51:246452 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:216453 NOTIFICATION_CRX_INSTALLER_DONE,
[email protected]97d6a5c2013-11-11 23:51:246454 content::NotificationService::AllSources());
[email protected]f4d5e1a2011-04-28 02:08:256455 EXPECT_TRUE(AddPendingSyncInstall());
[email protected]1d5e58b2013-01-31 08:41:406456 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
[email protected]145a317b2011-04-12 16:03:466457 EXPECT_TRUE(GetPendingIsFromSync());
6458 ASSERT_FALSE(IsCrxInstalled());
6459
6460 // Install pending as external prefs json would.
6461 AddPendingExternalPrefFileInstall();
[email protected]1d5e58b2013-01-31 08:41:406462 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
[email protected]145a317b2011-04-12 16:03:466463 ASSERT_FALSE(IsCrxInstalled());
6464
[email protected]6d057a0c2013-07-09 21:12:076465 // Another request from sync should be ignored.
[email protected]f4d5e1a2011-04-28 02:08:256466 EXPECT_FALSE(AddPendingSyncInstall());
[email protected]1d5e58b2013-01-31 08:41:406467 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
[email protected]145a317b2011-04-12 16:03:466468 ASSERT_FALSE(IsCrxInstalled());
6469
[email protected]97d6a5c2013-11-11 23:51:246470 observer.Wait();
6471 VerifyCrxInstall(crx_path_, INSTALL_NEW);
[email protected]145a317b2011-04-12 16:03:466472 ASSERT_TRUE(IsCrxInstalled());
6473}
6474
6475// Test that an install of an external CRX from an update overrides
6476// an install of the same extension from sync.
[email protected]ed8ee722011-04-22 06:49:446477TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
[email protected]145a317b2011-04-12 16:03:466478 InitializeEmptyExtensionService();
6479 ASSERT_FALSE(IsCrxInstalled());
6480
[email protected]f4d5e1a2011-04-28 02:08:256481 EXPECT_TRUE(AddPendingSyncInstall());
[email protected]1d5e58b2013-01-31 08:41:406482 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
[email protected]145a317b2011-04-12 16:03:466483 EXPECT_TRUE(GetPendingIsFromSync());
6484 ASSERT_FALSE(IsCrxInstalled());
6485
[email protected]9060d8b02012-01-13 02:14:306486 ASSERT_TRUE(AddPendingExternalPrefUrl());
[email protected]1d5e58b2013-01-31 08:41:406487 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
[email protected]145a317b2011-04-12 16:03:466488 EXPECT_FALSE(GetPendingIsFromSync());
6489 ASSERT_FALSE(IsCrxInstalled());
6490
[email protected]f4d5e1a2011-04-28 02:08:256491 EXPECT_FALSE(AddPendingSyncInstall());
[email protected]1d5e58b2013-01-31 08:41:406492 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
[email protected]145a317b2011-04-12 16:03:466493 EXPECT_FALSE(GetPendingIsFromSync());
6494 ASSERT_FALSE(IsCrxInstalled());
6495}
6496
[email protected]145a317b2011-04-12 16:03:466497// Test that an external install request stops sync from installing
6498// the same extension.
[email protected]ed8ee722011-04-22 06:49:446499TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
[email protected]145a317b2011-04-12 16:03:466500 InitializeEmptyExtensionService();
6501 ASSERT_FALSE(IsCrxInstalled());
6502
6503 // External prefs starts an install.
6504 AddPendingExternalPrefFileInstall();
6505
6506 // Crx installer was made, but has not yet run.
6507 ASSERT_FALSE(IsCrxInstalled());
6508
6509 // Before the CRX installer runs, Sync requests that the same extension
6510 // be installed. Should fail, because an external source is pending.
[email protected]97d6a5c2013-11-11 23:51:246511 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:216512 NOTIFICATION_CRX_INSTALLER_DONE,
[email protected]97d6a5c2013-11-11 23:51:246513 content::NotificationService::AllSources());
[email protected]145a317b2011-04-12 16:03:466514 ASSERT_FALSE(AddPendingSyncInstall());
6515
6516 // Wait for the external source to install.
[email protected]97d6a5c2013-11-11 23:51:246517 observer.Wait();
6518 VerifyCrxInstall(crx_path_, INSTALL_NEW);
[email protected]145a317b2011-04-12 16:03:466519 ASSERT_TRUE(IsCrxInstalled());
6520
6521 // Now that the extension is installed, sync request should fail
6522 // because the extension is already installed.
6523 ASSERT_FALSE(AddPendingSyncInstall());
6524}
[email protected]07c9f2f42012-02-29 18:45:226525
Owen Minb71016d2018-01-11 01:51:496526// Test that the blocked pending external extension should be ignored until
6527// it's unblocked. (crbug.com/797369)
6528TEST_F(ExtensionServiceTest, BlockedExternalExtension) {
6529 FeatureSwitch::ScopedOverride prompt(
6530 FeatureSwitch::prompt_for_external_extensions(), true);
6531
6532 InitializeEmptyExtensionService();
6533 MockExternalProvider* provider =
6534 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
6535
6536 service()->external_install_manager()->UpdateExternalExtensionAlert();
6537 EXPECT_FALSE(HasExternalInstallErrors(service()));
6538
6539 service()->BlockAllExtensions();
6540
6541 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
6542 data_dir().AppendASCII("page_action.crx"));
6543
6544 WaitForExternalExtensionInstalled();
6545 EXPECT_FALSE(HasExternalInstallErrors(service()));
6546
6547 service()->UnblockAllExtensions();
6548 EXPECT_TRUE(HasExternalInstallErrors(service()));
6549}
6550
[email protected]612a1cb12012-10-17 13:18:036551// Test that installing an external extension displays a GlobalError.
[email protected]d9a61e12012-11-14 02:43:476552TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
[email protected]00b5d0a52012-10-30 13:13:536553 FeatureSwitch::ScopedOverride prompt(
6554 FeatureSwitch::prompt_for_external_extensions(), true);
[email protected]612a1cb12012-10-17 13:18:036555
[email protected]07c9f2f42012-02-29 18:45:226556 InitializeEmptyExtensionService();
lazyboya00eafc2017-04-08 00:57:196557 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:226558 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]07c9f2f42012-02-29 18:45:226559
[email protected]374ceb6f2014-07-02 19:25:346560 service()->external_install_manager()->UpdateExternalExtensionAlert();
[email protected]07c9f2f42012-02-29 18:45:226561 // Should return false, meaning there aren't any extensions that the user
6562 // needs to know about.
lazyboy0b9b30f2016-01-05 03:15:376563 EXPECT_FALSE(HasExternalInstallErrors(service()));
[email protected]07c9f2f42012-02-29 18:45:226564
6565 // This is a normal extension, installed normally.
6566 // This should NOT trigger an alert.
[email protected]f484f8d52014-06-12 08:38:186567 base::FilePath path = data_dir().AppendASCII("good.crx");
[email protected]07c9f2f42012-02-29 18:45:226568 InstallCRX(path, INSTALL_NEW);
6569
[email protected]f484f8d52014-06-12 08:38:186570 service()->CheckForExternalUpdates();
Gabriel Charette01507a22017-09-27 21:30:086571 content::RunAllTasksUntilIdle();
lazyboy0b9b30f2016-01-05 03:15:376572 EXPECT_FALSE(HasExternalInstallErrors(service()));
[email protected]07c9f2f42012-02-29 18:45:226573
6574 // A hosted app, installed externally.
[email protected]2c495c42013-01-04 21:49:546575 // This should NOT trigger an alert.
[email protected]f484f8d52014-06-12 08:38:186576 provider->UpdateOrAddExtension(
6577 hosted_app, "1.0.0.0", data_dir().AppendASCII("hosted_app.crx"));
[email protected]07c9f2f42012-02-29 18:45:226578
lazyboy8a08c9d2017-04-11 19:53:226579 WaitForExternalExtensionInstalled();
lazyboy0b9b30f2016-01-05 03:15:376580 EXPECT_FALSE(HasExternalInstallErrors(service()));
[email protected]07c9f2f42012-02-29 18:45:226581
[email protected]612a1cb12012-10-17 13:18:036582 // Another normal extension, but installed externally.
6583 // This SHOULD trigger an alert.
[email protected]f484f8d52014-06-12 08:38:186584 provider->UpdateOrAddExtension(
6585 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
[email protected]612a1cb12012-10-17 13:18:036586
lazyboy8a08c9d2017-04-11 19:53:226587 WaitForExternalExtensionInstalled();
lazyboy0b9b30f2016-01-05 03:15:376588 EXPECT_TRUE(HasExternalInstallErrors(service()));
[email protected]07c9f2f42012-02-29 18:45:226589}
[email protected]612a1cb12012-10-17 13:18:036590
6591// Test that external extensions are initially disabled, and that enabling
6592// them clears the prompt.
[email protected]d9a61e12012-11-14 02:43:476593TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
[email protected]00b5d0a52012-10-30 13:13:536594 FeatureSwitch::ScopedOverride prompt(
6595 FeatureSwitch::prompt_for_external_extensions(), true);
[email protected]612a1cb12012-10-17 13:18:036596
6597 InitializeEmptyExtensionService();
lazyboya00eafc2017-04-08 00:57:196598 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:226599 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]612a1cb12012-10-17 13:18:036600
[email protected]f484f8d52014-06-12 08:38:186601 provider->UpdateOrAddExtension(
6602 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
lazyboy8a08c9d2017-04-11 19:53:226603 WaitForExternalExtensionInstalled();
[email protected]612a1cb12012-10-17 13:18:036604
lazyboy0b9b30f2016-01-05 03:15:376605 EXPECT_TRUE(HasExternalInstallErrors(service()));
[email protected]f484f8d52014-06-12 08:38:186606 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
[email protected]612a1cb12012-10-17 13:18:036607
6608 const Extension* extension =
[email protected]f484f8d52014-06-12 08:38:186609 registry()->disabled_extensions().GetByID(page_action);
[email protected]612a1cb12012-10-17 13:18:036610 EXPECT_TRUE(extension);
6611 EXPECT_EQ(page_action, extension->id());
6612
[email protected]f484f8d52014-06-12 08:38:186613 service()->EnableExtension(page_action);
lazyboy0b9b30f2016-01-05 03:15:376614 EXPECT_FALSE(HasExternalInstallErrors(service()));
[email protected]f484f8d52014-06-12 08:38:186615 EXPECT_TRUE(service()->IsExtensionEnabled(page_action));
[email protected]612a1cb12012-10-17 13:18:036616}
6617
mtomasz622f70d22017-01-27 03:36:266618// As for components, only external component extensions can be disabled.
6619TEST_F(ExtensionServiceTest, DisablingComponentExtensions) {
6620 InitializeEmptyExtensionService();
6621 service_->Init();
6622
Devlin Cronin8e5892f2018-10-04 00:13:436623 scoped_refptr<const Extension> external_component_extension = CreateExtension(
Devlin Cronin077ce1f2018-04-25 21:18:556624 "external_component_extension",
mtomasz622f70d22017-01-27 03:36:266625 base::FilePath(FILE_PATH_LITERAL("//external_component_extension")),
6626 Manifest::EXTERNAL_COMPONENT);
6627 service_->AddExtension(external_component_extension.get());
6628 EXPECT_TRUE(registry()->enabled_extensions().Contains(
6629 external_component_extension->id()));
6630 service_->DisableExtension(external_component_extension->id(),
Devlin Cronineea1b7a2018-05-26 02:46:216631 disable_reason::DISABLE_USER_ACTION);
mtomasz622f70d22017-01-27 03:36:266632 EXPECT_TRUE(registry()->disabled_extensions().Contains(
6633 external_component_extension->id()));
6634
Devlin Cronin8e5892f2018-10-04 00:13:436635 scoped_refptr<const Extension> component_extension = CreateExtension(
Devlin Cronin077ce1f2018-04-25 21:18:556636 "component_extension",
mtomasz622f70d22017-01-27 03:36:266637 base::FilePath(FILE_PATH_LITERAL("//component_extension")),
6638 Manifest::COMPONENT);
6639 service_->AddExtension(component_extension.get());
6640 EXPECT_TRUE(
6641 registry()->enabled_extensions().Contains(component_extension->id()));
6642 service_->DisableExtension(component_extension->id(),
Devlin Cronineea1b7a2018-05-26 02:46:216643 disable_reason::DISABLE_USER_ACTION);
mtomasz622f70d22017-01-27 03:36:266644 EXPECT_FALSE(
6645 registry()->disabled_extensions().Contains(component_extension->id()));
6646}
6647
[email protected]612a1cb12012-10-17 13:18:036648// Test that installing multiple external extensions works.
[email protected]404d1a22013-09-20 17:28:076649// Flaky on windows; http://crbug.com/295757 .
jyasskin3220c322015-08-10 22:19:066650// Causes race conditions with an in-process utility thread, so disable under
6651// TSan: https://crbug.com/518957
6652#if defined(OS_WIN) || defined(THREAD_SANITIZER)
[email protected]404d1a22013-09-20 17:28:076653#define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
6654#else
6655#define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
6656#endif
6657TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
[email protected]00b5d0a52012-10-30 13:13:536658 FeatureSwitch::ScopedOverride prompt(
6659 FeatureSwitch::prompt_for_external_extensions(), true);
[email protected]612a1cb12012-10-17 13:18:036660
6661 InitializeEmptyExtensionService();
lazyboya00eafc2017-04-08 00:57:196662 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:226663 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]612a1cb12012-10-17 13:18:036664
[email protected]f484f8d52014-06-12 08:38:186665 provider->UpdateOrAddExtension(
6666 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
6667 provider->UpdateOrAddExtension(
6668 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
6669 provider->UpdateOrAddExtension(
6670 theme_crx, "2.0", data_dir().AppendASCII("theme.crx"));
[email protected]612a1cb12012-10-17 13:18:036671
[email protected]6d057a0c2013-07-09 21:12:076672 int count = 3;
[email protected]97d6a5c2013-11-11 23:51:246673 content::WindowedNotificationObserver observer(
Devlin Cronineea1b7a2018-05-26 02:46:216674 NOTIFICATION_CRX_INSTALLER_DONE,
[email protected]97d6a5c2013-11-11 23:51:246675 base::Bind(&WaitForCountNotificationsCallback, &count));
[email protected]f484f8d52014-06-12 08:38:186676 service()->CheckForExternalUpdates();
[email protected]97d6a5c2013-11-11 23:51:246677 observer.Wait();
lazyboy0b9b30f2016-01-05 03:15:376678 EXPECT_TRUE(HasExternalInstallErrors(service()));
[email protected]f484f8d52014-06-12 08:38:186679 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
6680 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6681 EXPECT_FALSE(service()->IsExtensionEnabled(theme_crx));
[email protected]612a1cb12012-10-17 13:18:036682
[email protected]f484f8d52014-06-12 08:38:186683 service()->EnableExtension(page_action);
lazyboy0b9b30f2016-01-05 03:15:376684 EXPECT_FALSE(GetError(page_action));
6685 EXPECT_TRUE(GetError(good_crx));
6686 EXPECT_TRUE(GetError(theme_crx));
6687 EXPECT_TRUE(HasExternalInstallErrors(service()));
6688 EXPECT_FALSE(HasExternalInstallBubble(service()));
[email protected]2894a512014-06-26 19:03:566689
[email protected]f484f8d52014-06-12 08:38:186690 service()->EnableExtension(theme_crx);
lazyboy0b9b30f2016-01-05 03:15:376691 EXPECT_FALSE(GetError(page_action));
6692 EXPECT_FALSE(GetError(theme_crx));
6693 EXPECT_TRUE(GetError(good_crx));
6694 EXPECT_TRUE(HasExternalInstallErrors(service()));
6695 EXPECT_FALSE(HasExternalInstallBubble(service()));
[email protected]2894a512014-06-26 19:03:566696
[email protected]f484f8d52014-06-12 08:38:186697 service()->EnableExtension(good_crx);
lazyboy0b9b30f2016-01-05 03:15:376698 EXPECT_FALSE(GetError(page_action));
6699 EXPECT_FALSE(GetError(good_crx));
6700 EXPECT_FALSE(GetError(theme_crx));
6701 EXPECT_FALSE(HasExternalInstallErrors(service()));
6702 EXPECT_FALSE(HasExternalInstallBubble(service()));
6703}
6704
6705TEST_F(ExtensionServiceTest, MultipleExternalInstallErrors) {
6706 FeatureSwitch::ScopedOverride prompt(
6707 FeatureSwitch::prompt_for_external_extensions(), true);
6708 InitializeEmptyExtensionService();
lazyboy0b9b30f2016-01-05 03:15:376709
lazyboya00eafc2017-04-08 00:57:196710 MockExternalProvider* reg_provider =
lazyboy8a08c9d2017-04-11 19:53:226711 AddMockExternalProvider(Manifest::EXTERNAL_REGISTRY);
lazyboy0b9b30f2016-01-05 03:15:376712
6713 std::string extension_info[][3] = {
6714 // {id, path, version}
6715 {good_crx, "1.0.0.0", "good.crx"},
6716 {page_action, "1.0.0.0", "page_action.crx"},
6717 {minimal_platform_app_crx, "0.1", "minimal_platform_app.crx"}};
6718
Avi Drissman5f0fb8c2018-12-25 23:20:496719 for (size_t i = 0; i < base::size(extension_info); ++i) {
lazyboy0b9b30f2016-01-05 03:15:376720 reg_provider->UpdateOrAddExtension(
6721 extension_info[i][0], extension_info[i][1],
6722 data_dir().AppendASCII(extension_info[i][2]));
lazyboy8a08c9d2017-04-11 19:53:226723 WaitForExternalExtensionInstalled();
lazyboy0b9b30f2016-01-05 03:15:376724 const size_t expected_error_count = i + 1u;
6725 EXPECT_EQ(
6726 expected_error_count,
6727 service()->external_install_manager()->GetErrorsForTesting().size());
6728 EXPECT_FALSE(service()->IsExtensionEnabled(extension_info[i][0]));
6729 }
6730
6731 std::string extension_ids[] = {
6732 extension_info[0][0], extension_info[1][0], extension_info[2][0]
6733 };
6734
6735 // Each extension should end up in error.
6736 ASSERT_TRUE(GetError(extension_ids[0]));
6737 EXPECT_TRUE(GetError(extension_ids[1]));
6738 EXPECT_TRUE(GetError(extension_ids[2]));
6739
6740 // Accept the first extension, this will remove the error associated with
6741 // this extension. Also verify the other errors still exist.
rdevlin.cronin41593052016-01-08 01:40:126742 GetError(extension_ids[0])->OnInstallPromptDone(
6743 ExtensionInstallPrompt::Result::ACCEPTED);
lazyboy0b9b30f2016-01-05 03:15:376744 EXPECT_FALSE(GetError(extension_ids[0]));
6745 ASSERT_TRUE(GetError(extension_ids[1]));
6746 EXPECT_TRUE(GetError(extension_ids[2]));
6747
6748 // Abort the second extension.
rdevlin.cronin41593052016-01-08 01:40:126749 GetError(extension_ids[1])->OnInstallPromptDone(
6750 ExtensionInstallPrompt::Result::USER_CANCELED);
lazyboy0b9b30f2016-01-05 03:15:376751 EXPECT_FALSE(GetError(extension_ids[0]));
6752 EXPECT_FALSE(GetError(extension_ids[1]));
6753 ASSERT_TRUE(GetError(extension_ids[2]));
6754
6755 // Finally, re-enable the third extension, all errors should be removed.
6756 service()->EnableExtension(extension_ids[2]);
6757 EXPECT_FALSE(GetError(extension_ids[0]));
6758 EXPECT_FALSE(GetError(extension_ids[1]));
6759 EXPECT_FALSE(GetError(extension_ids[2]));
6760
6761 EXPECT_FALSE(HasExternalInstallErrors(service_));
[email protected]aa55be7f2013-04-22 20:56:046762}
6763
Karan Bhatiae9d5166f2017-07-17 22:06:436764// Regression test for crbug.com/739142. Verifies that no UAF occurs when
6765// ExternalInstallError needs to be deleted asynchronously.
6766TEST_F(ExtensionServiceTest, InstallPromptAborted) {
6767 FeatureSwitch::ScopedOverride prompt(
6768 FeatureSwitch::prompt_for_external_extensions(), true);
6769 InitializeEmptyExtensionService();
6770
6771 MockExternalProvider* reg_provider =
6772 AddMockExternalProvider(Manifest::EXTERNAL_REGISTRY);
6773
6774 reg_provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
6775 data_dir().AppendASCII("good.crx"));
6776 WaitForExternalExtensionInstalled();
6777 EXPECT_EQ(
6778 1u, service()->external_install_manager()->GetErrorsForTesting().size());
6779 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6780 EXPECT_TRUE(GetError(good_crx));
6781
6782 // Abort the extension install prompt. This should cause the
6783 // ExternalInstallError to be deleted asynchronously.
6784 GetError(good_crx)->OnInstallPromptDone(
6785 ExtensionInstallPrompt::Result::ABORTED);
6786 EXPECT_TRUE(GetError(good_crx));
6787 base::RunLoop().RunUntilIdle();
6788 EXPECT_FALSE(GetError(good_crx));
6789
6790 EXPECT_FALSE(HasExternalInstallErrors(service_));
6791}
6792
lazyboy1899eec42016-03-08 19:00:506793TEST_F(ExtensionServiceTest, MultipleExternalInstallBubbleErrors) {
6794 FeatureSwitch::ScopedOverride prompt(
6795 FeatureSwitch::prompt_for_external_extensions(), true);
6796 // This sets up the ExtensionPrefs used by our ExtensionService to be
6797 // post-first run.
6798 ExtensionServiceInitParams params = CreateDefaultInitParams();
6799 params.is_first_run = false;
6800 InitializeExtensionService(params);
6801
lazyboya00eafc2017-04-08 00:57:196802 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:226803 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
lazyboy1899eec42016-03-08 19:00:506804
6805 std::vector<BubbleErrorsTestData> data;
vabr9142fe22016-09-08 13:19:226806 data.push_back(BubbleErrorsTestData(
6807 updates_from_webstore, "1",
6808 temp_dir().GetPath().AppendASCII("webstore.crx"), 1u));
6809 data.push_back(BubbleErrorsTestData(
6810 updates_from_webstore2, "1",
6811 temp_dir().GetPath().AppendASCII("webstore2.crx"), 2u));
lazyboy1899eec42016-03-08 19:00:506812 data.push_back(BubbleErrorsTestData(good_crx, "1.0.0.0",
6813 data_dir().AppendASCII("good.crx"), 2u));
6814
6815 PackCRX(data_dir().AppendASCII("update_from_webstore"),
6816 data_dir().AppendASCII("update_from_webstore.pem"), data[0].crx_path);
6817 PackCRX(data_dir().AppendASCII("update_from_webstore2"),
6818 data_dir().AppendASCII("update_from_webstore2.pem"),
6819 data[1].crx_path);
6820
6821 // Install extensions from |data| one by one and expect each of them to result
6822 // in an error. The first two extensions are from webstore, so they will
6823 // trigger BUBBLE_ALERT type errors. After each step, we verify that we got
6824 // the expected number of errors in external_install_manager(). We also verify
6825 // that only the first BUBBLE_ALERT error is shown.
6826 for (size_t i = 0; i < data.size(); ++i) {
Evan Stade2ec8dd82019-06-25 17:53:216827 test::GlobalErrorWaiter error_waiter(profile());
lazyboy1899eec42016-03-08 19:00:506828 provider->UpdateOrAddExtension(data[i].id, data[i].version,
6829 data[i].crx_path);
lazyboy8a08c9d2017-04-11 19:53:226830 WaitForExternalExtensionInstalled();
lazyboy1899eec42016-03-08 19:00:506831 // Make sure ExternalInstallError::OnDialogReady() fires.
Evan Stade2ec8dd82019-06-25 17:53:216832 error_waiter.Wait();
lazyboy1899eec42016-03-08 19:00:506833
6834 const size_t expected_error_count = i + 1u;
6835 std::vector<ExternalInstallError*> errors =
6836 service_->external_install_manager()->GetErrorsForTesting();
6837 EXPECT_EQ(expected_error_count, errors.size());
6838 EXPECT_EQ(data[i].expected_bubble_error_count,
6839 GetExternalInstallBubbleCount(service()));
6840 EXPECT_TRUE(service()
6841 ->external_install_manager()
6842 ->has_currently_visible_install_alert());
6843 // Make sure that the first error is only being shown.
6844 EXPECT_EQ(errors[0], service()
6845 ->external_install_manager()
6846 ->currently_visible_install_alert_for_testing());
6847 EXPECT_FALSE(service()->IsExtensionEnabled(data[i].id));
6848 }
6849
6850 // Cancel all the install prompts.
6851 for (size_t i = 0; i < data.size(); ++i) {
6852 const std::string& extension_id = data[i].id;
6853 EXPECT_TRUE(GetError(extension_id));
6854 GetError(extension_id)
6855 ->OnInstallPromptDone(ExtensionInstallPrompt::Result::USER_CANCELED);
6856 EXPECT_FALSE(GetError(extension_id));
6857 }
6858 EXPECT_FALSE(service()
6859 ->external_install_manager()
6860 ->has_currently_visible_install_alert());
6861 EXPECT_EQ(0u, GetExternalInstallBubbleCount(service()));
6862 EXPECT_FALSE(HasExternalInstallErrors(service()));
6863
6864 // Add a new webstore install. Verify that this shows an error bubble since
6865 // there are no error bubbles pending at this point. Also verify that the
6866 // error bubble is for this newly added extension.
6867 {
6868 base::FilePath webstore_crx_three =
vabr9142fe22016-09-08 13:19:226869 temp_dir().GetPath().AppendASCII("webstore3.crx");
lazyboy1899eec42016-03-08 19:00:506870 PackCRX(data_dir().AppendASCII("update_from_webstore3"),
6871 data_dir().AppendASCII("update_from_webstore3.pem"),
6872 webstore_crx_three);
6873
Evan Stade2ec8dd82019-06-25 17:53:216874 test::GlobalErrorWaiter error_waiter(profile());
lazyboy1899eec42016-03-08 19:00:506875 provider->UpdateOrAddExtension(
6876 updates_from_webstore3, "1",
vabr9142fe22016-09-08 13:19:226877 temp_dir().GetPath().AppendASCII("webstore3.crx"));
lazyboy8a08c9d2017-04-11 19:53:226878 WaitForExternalExtensionInstalled();
lazyboy1899eec42016-03-08 19:00:506879 // Make sure ExternalInstallError::OnDialogReady() fires.
Evan Stade2ec8dd82019-06-25 17:53:216880 error_waiter.Wait();
lazyboy1899eec42016-03-08 19:00:506881
6882 std::vector<ExternalInstallError*> errors =
6883 service_->external_install_manager()->GetErrorsForTesting();
6884 EXPECT_EQ(1u, errors.size());
6885 EXPECT_EQ(1u, GetExternalInstallBubbleCount(service()));
6886 EXPECT_TRUE(service()
6887 ->external_install_manager()
6888 ->has_currently_visible_install_alert());
6889 // Verify that the visible alert is for the current error.
6890 EXPECT_EQ(errors[0], service()
6891 ->external_install_manager()
6892 ->currently_visible_install_alert_for_testing());
6893 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore3));
6894 }
6895}
6896
6897// Verifies that an error alert of type BUBBLE_ALERT does not replace an
6898// existing visible alert that was previously opened by clicking menu item.
6899TEST_F(ExtensionServiceTest, BubbleAlertDoesNotHideAnotherAlertFromMenu) {
6900 FeatureSwitch::ScopedOverride prompt(
6901 FeatureSwitch::prompt_for_external_extensions(), true);
6902 // This sets up the ExtensionPrefs used by our ExtensionService to be
6903 // post-first run.
6904 ExtensionServiceInitParams params = CreateDefaultInitParams();
6905 params.is_first_run = false;
6906 InitializeExtensionService(params);
6907
lazyboya00eafc2017-04-08 00:57:196908 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:226909 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
lazyboy1899eec42016-03-08 19:00:506910
6911 std::vector<BubbleErrorsTestData> data;
vabr9142fe22016-09-08 13:19:226912 data.push_back(BubbleErrorsTestData(
6913 updates_from_webstore, "1",
6914 temp_dir().GetPath().AppendASCII("webstore.crx"), 1u));
6915 data.push_back(BubbleErrorsTestData(
6916 updates_from_webstore2, "1",
6917 temp_dir().GetPath().AppendASCII("webstore2.crx"), 2u));
lazyboy1899eec42016-03-08 19:00:506918
6919 PackCRX(data_dir().AppendASCII("update_from_webstore"),
6920 data_dir().AppendASCII("update_from_webstore.pem"), data[0].crx_path);
6921 PackCRX(data_dir().AppendASCII("update_from_webstore2"),
6922 data_dir().AppendASCII("update_from_webstore2.pem"),
6923 data[1].crx_path);
6924 {
Evan Stade2ec8dd82019-06-25 17:53:216925 test::GlobalErrorWaiter error_waiter(profile());
lazyboy1899eec42016-03-08 19:00:506926 provider->UpdateOrAddExtension(data[0].id, data[0].version,
6927 data[0].crx_path);
lazyboy8a08c9d2017-04-11 19:53:226928 WaitForExternalExtensionInstalled();
lazyboy1899eec42016-03-08 19:00:506929 // Make sure ExternalInstallError::OnDialogReady() fires.
Evan Stade2ec8dd82019-06-25 17:53:216930 error_waiter.Wait();
lazyboy1899eec42016-03-08 19:00:506931
6932 std::vector<ExternalInstallError*> errors =
6933 service_->external_install_manager()->GetErrorsForTesting();
6934 EXPECT_EQ(1u, errors.size());
6935 EXPECT_EQ(1u, GetExternalInstallBubbleCount(service()));
6936 EXPECT_TRUE(service()
6937 ->external_install_manager()
6938 ->has_currently_visible_install_alert());
6939 // Verify that the visible alert is for the current error.
6940 EXPECT_EQ(errors[0], service()
6941 ->external_install_manager()
6942 ->currently_visible_install_alert_for_testing());
6943 }
6944
6945 ExternalInstallError* first_extension_error = GetError(data[0].id);
6946
6947 // Close the bubble alert.
6948 GlobalError* global_error =
6949 GlobalErrorServiceFactory::GetForProfile(profile())
6950 ->GetHighestSeverityGlobalErrorWithAppMenuItem();
6951 first_extension_error->DidCloseBubbleView();
6952
6953 // Bring the bubble alert error again by clicking its menu item.
6954 global_error->ExecuteMenuItem(nullptr);
6955
6956 // Install another webstore extension that will trigger an erorr of type
6957 // BUBBLE_ALERT.
6958 // Make sure that this bubble alert does not replace the current bubble alert.
6959 {
Evan Stade2ec8dd82019-06-25 17:53:216960 test::GlobalErrorWaiter error_waiter(profile());
lazyboy1899eec42016-03-08 19:00:506961 provider->UpdateOrAddExtension(data[1].id, data[1].version,
6962 data[1].crx_path);
lazyboy8a08c9d2017-04-11 19:53:226963 WaitForExternalExtensionInstalled();
lazyboy1899eec42016-03-08 19:00:506964 // Make sure ExternalInstallError::OnDialogReady() fires.
Evan Stade2ec8dd82019-06-25 17:53:216965 error_waiter.Wait();
lazyboy1899eec42016-03-08 19:00:506966
6967 std::vector<ExternalInstallError*> errors =
6968 service_->external_install_manager()->GetErrorsForTesting();
6969 EXPECT_EQ(2u, errors.size());
6970 EXPECT_EQ(2u, GetExternalInstallBubbleCount(service()));
6971 EXPECT_TRUE(service()
6972 ->external_install_manager()
6973 ->has_currently_visible_install_alert());
6974 // Verify that the old bubble alert was *not* replaced by the new alert.
6975 EXPECT_EQ(first_extension_error,
6976 service()
6977 ->external_install_manager()
6978 ->currently_visible_install_alert_for_testing());
6979 }
6980}
6981
[email protected]aa55be7f2013-04-22 20:56:046982// Test that there is a bubble for external extensions that update
[email protected]b3aa7182013-04-25 04:45:236983// from the webstore if the profile is not new.
6984TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
[email protected]aa55be7f2013-04-22 20:56:046985 FeatureSwitch::ScopedOverride prompt(
6986 FeatureSwitch::prompt_for_external_extensions(), true);
6987
[email protected]b3aa7182013-04-25 04:45:236988 // This sets up the ExtensionPrefs used by our ExtensionService to be
6989 // post-first run.
[email protected]371662e372013-10-17 22:05:226990 ExtensionServiceInitParams params = CreateDefaultInitParams();
6991 params.is_first_run = false;
6992 InitializeExtensionService(params);
[email protected]aa55be7f2013-04-22 20:56:046993
vabr9142fe22016-09-08 13:19:226994 base::FilePath crx_path = temp_dir().GetPath().AppendASCII("webstore.crx");
[email protected]f484f8d52014-06-12 08:38:186995 PackCRX(data_dir().AppendASCII("update_from_webstore"),
6996 data_dir().AppendASCII("update_from_webstore.pem"),
[email protected]aa55be7f2013-04-22 20:56:046997 crx_path);
6998
lazyboya00eafc2017-04-08 00:57:196999 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:227000 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]aa55be7f2013-04-22 20:56:047001 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
lazyboy8a08c9d2017-04-11 19:53:227002 WaitForExternalExtensionInstalled();
[email protected]460c6712013-04-24 07:20:017003
lazyboy0b9b30f2016-01-05 03:15:377004 EXPECT_TRUE(HasExternalInstallErrors(service()));
7005 ASSERT_TRUE(GetError(updates_from_webstore));
7006 EXPECT_EQ(ExternalInstallError::BUBBLE_ALERT,
7007 GetError(updates_from_webstore)->alert_type());
[email protected]f484f8d52014-06-12 08:38:187008 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
[email protected]612a1cb12012-10-17 13:18:037009}
[email protected]460c6712013-04-24 07:20:017010
7011// Test that there is no bubble for external extensions if the profile is new.
7012TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
7013 FeatureSwitch::ScopedOverride prompt(
7014 FeatureSwitch::prompt_for_external_extensions(), true);
7015
7016 InitializeEmptyExtensionService();
7017
vabr9142fe22016-09-08 13:19:227018 base::FilePath crx_path = temp_dir().GetPath().AppendASCII("webstore.crx");
[email protected]f484f8d52014-06-12 08:38:187019 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7020 data_dir().AppendASCII("update_from_webstore.pem"),
[email protected]460c6712013-04-24 07:20:017021 crx_path);
7022
lazyboya00eafc2017-04-08 00:57:197023 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:227024 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]460c6712013-04-24 07:20:017025 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
lazyboy8a08c9d2017-04-11 19:53:227026 WaitForExternalExtensionInstalled();
[email protected]460c6712013-04-24 07:20:017027
lazyboy0b9b30f2016-01-05 03:15:377028 EXPECT_TRUE(HasExternalInstallErrors(service()));
7029 ASSERT_TRUE(GetError(updates_from_webstore));
7030 EXPECT_NE(ExternalInstallError::BUBBLE_ALERT,
7031 GetError(updates_from_webstore)->alert_type());
[email protected]f484f8d52014-06-12 08:38:187032 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
[email protected]460c6712013-04-24 07:20:017033}
[email protected]9f3c8532013-07-31 19:52:077034
[email protected]2894a512014-06-26 19:03:567035// Test that clicking to remove the extension on an external install warning
7036// uninstalls the extension.
7037TEST_F(ExtensionServiceTest, ExternalInstallClickToRemove) {
7038 FeatureSwitch::ScopedOverride prompt(
7039 FeatureSwitch::prompt_for_external_extensions(), true);
7040
7041 ExtensionServiceInitParams params = CreateDefaultInitParams();
7042 params.is_first_run = false;
7043 InitializeExtensionService(params);
7044
vabr9142fe22016-09-08 13:19:227045 base::FilePath crx_path = temp_dir().GetPath().AppendASCII("webstore.crx");
[email protected]2894a512014-06-26 19:03:567046 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7047 data_dir().AppendASCII("update_from_webstore.pem"),
7048 crx_path);
7049
lazyboya00eafc2017-04-08 00:57:197050 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:227051 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]2894a512014-06-26 19:03:567052 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
lazyboy8a08c9d2017-04-11 19:53:227053 WaitForExternalExtensionInstalled();
[email protected]2894a512014-06-26 19:03:567054
lazyboy0b9b30f2016-01-05 03:15:377055 EXPECT_TRUE(HasExternalInstallErrors(service_));
[email protected]2894a512014-06-26 19:03:567056
7057 // We check both enabled and disabled, since these are "eventually exclusive"
7058 // sets.
7059 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7060 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7061
7062 // Click the negative response.
lazyboy0b9b30f2016-01-05 03:15:377063 service_->external_install_manager()
7064 ->GetErrorsForTesting()[0]
rdevlin.cronin41593052016-01-08 01:40:127065 ->OnInstallPromptDone(ExtensionInstallPrompt::Result::USER_CANCELED);
[email protected]2894a512014-06-26 19:03:567066 // The Extension should be uninstalled.
7067 EXPECT_FALSE(registry()->GetExtensionById(updates_from_webstore,
7068 ExtensionRegistry::EVERYTHING));
7069 // The error should be removed.
lazyboy0b9b30f2016-01-05 03:15:377070 EXPECT_FALSE(HasExternalInstallErrors(service_));
[email protected]2894a512014-06-26 19:03:567071}
7072
7073// Test that clicking to keep the extension on an external install warning
7074// re-enables the extension.
7075TEST_F(ExtensionServiceTest, ExternalInstallClickToKeep) {
7076 FeatureSwitch::ScopedOverride prompt(
7077 FeatureSwitch::prompt_for_external_extensions(), true);
7078
7079 ExtensionServiceInitParams params = CreateDefaultInitParams();
7080 params.is_first_run = false;
7081 InitializeExtensionService(params);
7082
vabr9142fe22016-09-08 13:19:227083 base::FilePath crx_path = temp_dir().GetPath().AppendASCII("webstore.crx");
[email protected]2894a512014-06-26 19:03:567084 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7085 data_dir().AppendASCII("update_from_webstore.pem"),
7086 crx_path);
7087
lazyboya00eafc2017-04-08 00:57:197088 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:227089 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
[email protected]2894a512014-06-26 19:03:567090 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
lazyboy8a08c9d2017-04-11 19:53:227091 WaitForExternalExtensionInstalled();
[email protected]2894a512014-06-26 19:03:567092
lazyboy0b9b30f2016-01-05 03:15:377093 EXPECT_TRUE(HasExternalInstallErrors(service_));
[email protected]2894a512014-06-26 19:03:567094
7095 // We check both enabled and disabled, since these are "eventually exclusive"
7096 // sets.
7097 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7098 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7099
7100 // Accept the extension.
lazyboy0b9b30f2016-01-05 03:15:377101 service_->external_install_manager()
7102 ->GetErrorsForTesting()[0]
rdevlin.cronin41593052016-01-08 01:40:127103 ->OnInstallPromptDone(ExtensionInstallPrompt::Result::ACCEPTED);
[email protected]2894a512014-06-26 19:03:567104
7105 // It should be enabled again.
7106 EXPECT_TRUE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7107 EXPECT_FALSE(
7108 registry()->disabled_extensions().GetByID(updates_from_webstore));
7109
7110 // The error should be removed.
lazyboy0b9b30f2016-01-05 03:15:377111 EXPECT_FALSE(HasExternalInstallErrors(service_));
[email protected]2894a512014-06-26 19:03:567112}
7113
rdevlin.cronine1456712016-12-29 22:47:287114// Test that the external install bubble only takes disabled extensions into
7115// account - enabled extensions, even those that weren't acknowledged, should
7116// not be warned about. This lets us grandfather extensions in.
7117TEST_F(ExtensionServiceTest,
7118 ExternalInstallBubbleDoesntShowForEnabledExtensions) {
7119 auto external_prompt_override =
Jinho Bangb5216cec2018-01-17 19:43:117120 std::make_unique<FeatureSwitch::ScopedOverride>(
rdevlin.cronine1456712016-12-29 22:47:287121 FeatureSwitch::prompt_for_external_extensions(), false);
7122 InitializeEmptyExtensionService();
7123
7124 // Register and install an external extension.
lazyboya00eafc2017-04-08 00:57:197125 MockExternalProvider* provider =
lazyboy8a08c9d2017-04-11 19:53:227126 AddMockExternalProvider(Manifest::EXTERNAL_PREF);
rdevlin.cronine1456712016-12-29 22:47:287127 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
7128 data_dir().AppendASCII("good.crx"));
7129
7130 WaitForExternalExtensionInstalled();
7131
7132 EXPECT_TRUE(registry()->enabled_extensions().Contains(good_crx));
7133 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7134 EXPECT_FALSE(prefs->IsExternalExtensionAcknowledged(good_crx));
Devlin Cronineea1b7a2018-05-26 02:46:217135 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
rdevlin.cronine1456712016-12-29 22:47:287136
7137 // We explicitly reset the override first. ScopedOverrides reset the value
7138 // to the original value on destruction, but if we reset by passing a new
7139 // object, the new object is constructed (overriding the current value)
7140 // before the old is destructed (which will immediately reset to the
7141 // original).
7142 external_prompt_override.reset();
Jinho Bangb5216cec2018-01-17 19:43:117143 external_prompt_override = std::make_unique<FeatureSwitch::ScopedOverride>(
rdevlin.cronine1456712016-12-29 22:47:287144 FeatureSwitch::prompt_for_external_extensions(), true);
7145
Devlin Cronineea1b7a2018-05-26 02:46:217146 ExternalInstallManager* external_manager =
rdevlin.cronine1456712016-12-29 22:47:287147 service()->external_install_manager();
7148 external_manager->UpdateExternalExtensionAlert();
7149 EXPECT_FALSE(external_manager->has_currently_visible_install_alert());
7150 EXPECT_TRUE(external_manager->GetErrorsForTesting().empty());
7151
7152 provider->UpdateOrAddExtension(good_crx, "1.0.0.1",
7153 data_dir().AppendASCII("good2.crx"));
7154
7155 WaitForExternalExtensionInstalled();
7156
7157 external_manager->UpdateExternalExtensionAlert();
7158 EXPECT_FALSE(external_manager->has_currently_visible_install_alert());
7159 EXPECT_TRUE(external_manager->GetErrorsForTesting().empty());
7160}
7161
[email protected]9f3c8532013-07-31 19:52:077162TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
7163 InitializeEmptyExtensionService();
7164
Devlin Cronin8e5892f2018-10-04 00:13:437165 scoped_refptr<const Extension> extension =
7166 ExtensionBuilder("extension").Build();
[email protected]9f3c8532013-07-31 19:52:077167 ASSERT_TRUE(extension.get());
7168 const std::string& id = extension->id();
7169
7170 std::set<std::string> id_set;
7171 id_set.insert(id);
[email protected]9f3c8532013-07-31 19:52:077172
Devlin Cronineea1b7a2018-05-26 02:46:217173 TestExtensionRegistryObserver observer(ExtensionRegistry::Get(profile()));
[email protected]9f3c8532013-07-31 19:52:077174 // Installation should be allowed but the extension should never have been
7175 // loaded and it should be blacklisted in prefs.
[email protected]4a1d9c0d2014-06-13 12:50:117176 service()->OnExtensionInstalled(
Devlin Cronineea1b7a2018-05-26 02:46:217177 extension.get(), syncer::StringOrdinal(),
7178 (kInstallFlagIsBlacklistedForMalware | kInstallFlagInstallImmediately));
Gabriel Charette01507a22017-09-27 21:30:087179 content::RunAllTasksUntilIdle();
[email protected]9f3c8532013-07-31 19:52:077180
7181 // Extension was installed but not loaded.
limasdfe1d046f2015-10-29 00:48:007182 observer.WaitForExtensionWillBeInstalled();
[email protected]f484f8d52014-06-12 08:38:187183 EXPECT_TRUE(service()->GetInstalledExtension(id));
[email protected]5fdfa562013-12-27 17:43:597184
[email protected]f484f8d52014-06-12 08:38:187185 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7186 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id));
[email protected]5fdfa562013-12-27 17:43:597187
[email protected]f484f8d52014-06-12 08:38:187188 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id));
7189 EXPECT_TRUE(
7190 ExtensionPrefs::Get(profile())->IsBlacklistedExtensionAcknowledged(id));
[email protected]9f3c8532013-07-31 19:52:077191}
[email protected]59ee99d2013-10-11 15:46:167192
asargent96c7ec42016-05-27 02:45:477193// Test that we won't allow enabling a blacklisted extension.
7194TEST_F(ExtensionServiceTest, CannotEnableBlacklistedExtension) {
7195 InitializeGoodInstalledExtensionService();
7196 service()->Init();
7197 ASSERT_FALSE(registry()->enabled_extensions().is_empty());
7198
7199 // Blacklist the first extension; then try enabling it.
7200 std::string id = (*(registry()->enabled_extensions().begin()))->id();
7201 service()->BlacklistExtensionForTest(id);
7202 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7203 EXPECT_FALSE(registry()->disabled_extensions().Contains(id));
7204 service()->EnableExtension(id);
7205 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7206 EXPECT_FALSE(registry()->disabled_extensions().Contains(id));
7207 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id));
7208 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id));
7209
Devlin Cronineea1b7a2018-05-26 02:46:217210 service()->DisableExtension(id, disable_reason::DISABLE_USER_ACTION);
asargent96c7ec42016-05-27 02:45:477211 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7212 EXPECT_FALSE(registry()->disabled_extensions().Contains(id));
7213 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id));
7214 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id));
7215}
7216
elijahtaylor49c09c5c2016-07-09 01:06:227217// Test that calls to disable Shared Modules do not work.
7218TEST_F(ExtensionServiceTest, CannotDisableSharedModules) {
7219 InitializeEmptyExtensionService();
Devlin Cronin8e5892f2018-10-04 00:13:437220 scoped_refptr<const Extension> extension =
Devlin Cronin05b047d2017-08-22 21:53:557221 ExtensionBuilder("Shared Module")
Devlin Cronin98cd6582018-05-08 19:18:127222 .SetManifestPath({"export", "resources"},
Devlin Cronineea1b7a2018-05-26 02:46:217223 ListBuilder().Append("foo.js").Build())
Devlin Cronin05b047d2017-08-22 21:53:557224 .AddFlags(Extension::FROM_WEBSTORE)
7225 .Build();
elijahtaylor49c09c5c2016-07-09 01:06:227226
7227 service()->OnExtensionInstalled(extension.get(), syncer::StringOrdinal(),
Devlin Cronineea1b7a2018-05-26 02:46:217228 kInstallFlagInstallImmediately);
elijahtaylor49c09c5c2016-07-09 01:06:227229
7230 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7231 // Try to disable the extension.
Minh X. Nguyen45479012017-08-18 21:35:367232 service()->DisableExtension(extension->id(),
Devlin Cronineea1b7a2018-05-26 02:46:217233 disable_reason::DISABLE_USER_ACTION);
elijahtaylor49c09c5c2016-07-09 01:06:227234 // Shared Module should still be enabled.
7235 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7236}
7237
asargent96c7ec42016-05-27 02:45:477238// Make sure we can uninstall a blacklisted extension
7239TEST_F(ExtensionServiceTest, UninstallBlacklistedExtension) {
7240 InitializeGoodInstalledExtensionService();
7241 service()->Init();
7242 ASSERT_FALSE(registry()->enabled_extensions().is_empty());
7243
7244 // Blacklist the first extension; then try uninstalling it.
7245 std::string id = (*(registry()->enabled_extensions().begin()))->id();
7246 service()->BlacklistExtensionForTest(id);
7247 EXPECT_NE(nullptr, registry()->GetInstalledExtension(id));
7248 base::string16 error;
Devlin Cronineea1b7a2018-05-26 02:46:217249 EXPECT_TRUE(service()->UninstallExtension(id, UNINSTALL_REASON_USER_INITIATED,
7250 nullptr));
asargent96c7ec42016-05-27 02:45:477251 EXPECT_EQ(nullptr, registry()->GetInstalledExtension(id));
7252}
7253
[email protected]ebe07772014-05-22 04:16:067254// Tests a profile being destroyed correctly disables extensions.
7255TEST_F(ExtensionServiceTest, DestroyingProfileClearsExtensions) {
7256 InitializeEmptyExtensionService();
7257
[email protected]f484f8d52014-06-12 08:38:187258 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
limasdf0deef2042017-05-03 19:17:177259 EXPECT_NE(UnloadedExtensionReason::PROFILE_SHUTDOWN, unloaded_reason_);
[email protected]f484f8d52014-06-12 08:38:187260 EXPECT_EQ(1u, registry()->enabled_extensions().size());
7261 EXPECT_EQ(0u, registry()->disabled_extensions().size());
7262 EXPECT_EQ(0u, registry()->terminated_extensions().size());
7263 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
[email protected]ebe07772014-05-22 04:16:067264
Evan Staded89e11c2019-09-05 18:08:567265 service()->OnProfileMarkedForPermanentDeletion(profile());
limasdf0deef2042017-05-03 19:17:177266 EXPECT_EQ(UnloadedExtensionReason::PROFILE_SHUTDOWN, unloaded_reason_);
[email protected]f484f8d52014-06-12 08:38:187267 EXPECT_EQ(0u, registry()->enabled_extensions().size());
7268 EXPECT_EQ(0u, registry()->disabled_extensions().size());
7269 EXPECT_EQ(0u, registry()->terminated_extensions().size());
7270 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
[email protected]ebe07772014-05-22 04:16:067271}
asargente4de9f92016-09-15 01:40:067272
7273// Test that updating a corrupt extension removes the DISABLE_CORRUPTED disable
7274// reason.
7275TEST_F(ExtensionServiceTest, CorruptExtensionUpdate) {
7276 InitializeEmptyExtensionService();
7277
7278 base::FilePath v1_path = data_dir().AppendASCII("good.crx");
7279 const Extension* v1 = InstallCRX(v1_path, INSTALL_NEW);
7280 std::string id = v1->id();
7281
Devlin Cronineea1b7a2018-05-26 02:46:217282 service()->DisableExtension(id, disable_reason::DISABLE_CORRUPTED);
asargente4de9f92016-09-15 01:40:067283
7284 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7285 EXPECT_TRUE(registry()->disabled_extensions().Contains(id));
Devlin Cronineea1b7a2018-05-26 02:46:217286 EXPECT_TRUE(prefs->HasDisableReason(id, disable_reason::DISABLE_CORRUPTED));
asargente4de9f92016-09-15 01:40:067287
7288 base::FilePath v2_path = data_dir().AppendASCII("good2.crx");
7289 UpdateExtension(id, v2_path, ENABLED);
7290
7291 EXPECT_FALSE(registry()->disabled_extensions().Contains(id));
Devlin Cronineea1b7a2018-05-26 02:46:217292 EXPECT_FALSE(prefs->HasDisableReason(id, disable_reason::DISABLE_CORRUPTED));
asargente4de9f92016-09-15 01:40:067293}
rdevlin.croninf87d15f2017-01-26 22:57:197294
7295// Try re-enabling a reloading extension. Regression test for crbug.com/676815.
7296TEST_F(ExtensionServiceTest, ReloadAndReEnableExtension) {
7297 InitializeEmptyExtensionService();
7298
7299 // Add an extension in an unpacked location.
7300 scoped_refptr<const Extension> extension =
Devlin Cronineea1b7a2018-05-26 02:46:217301 ChromeTestExtensionLoader(profile()).LoadExtension(
7302 data_dir().AppendASCII("simple_with_file"));
rdevlin.croninf87d15f2017-01-26 22:57:197303 const std::string kExtensionId = extension->id();
7304 ASSERT_TRUE(extension);
Devlin Cronineea1b7a2018-05-26 02:46:217305 ASSERT_TRUE(Manifest::IsUnpackedLocation(extension->location()));
rdevlin.croninf87d15f2017-01-26 22:57:197306 EXPECT_TRUE(registry()->enabled_extensions().Contains(kExtensionId));
7307
7308 // Begin the reload process.
7309 service()->ReloadExtension(extension->id());
7310 EXPECT_TRUE(registry()->disabled_extensions().Contains(kExtensionId));
7311
7312 // While the extension is reloading, try to re-enable it. This is the flow
7313 // that could happen if, e.g., the user hit the enable toggle in the
7314 // chrome://extensions page while it was reloading.
7315 service()->GrantPermissionsAndEnableExtension(extension.get());
7316 EXPECT_FALSE(registry()->enabled_extensions().Contains(kExtensionId));
7317
7318 // Wait for the reload to complete. This previously crashed (see
7319 // crbug.com/676815).
Gabriel Charette01507a22017-09-27 21:30:087320 content::RunAllTasksUntilIdle();
rdevlin.croninf87d15f2017-01-26 22:57:197321 // The extension should be enabled again...
7322 EXPECT_TRUE(registry()->enabled_extensions().Contains(kExtensionId));
7323 // ...and should have reloaded (for ease, we just compare the extension
7324 // objects).
7325 EXPECT_NE(extension, registry()->enabled_extensions().GetByID(kExtensionId));
7326}
rdevlin.cronin07f10c12017-02-08 19:37:587327
7328// Test reloading a shared module. Regression test for crbug.com/676815.
7329TEST_F(ExtensionServiceTest, ReloadSharedModule) {
7330 InitializeEmptyExtensionService();
7331
7332 // Add a shared module and an extension that depends on it (the latter is
7333 // important to ensure we don't remove the unused shared module).
7334 scoped_refptr<const Extension> shared_module =
Devlin Cronineea1b7a2018-05-26 02:46:217335 ChromeTestExtensionLoader(profile()).LoadExtension(
rdevlin.cronin07f10c12017-02-08 19:37:587336 data_dir().AppendASCII("api_test/shared_module/shared"));
7337 scoped_refptr<const Extension> dependent =
Devlin Cronineea1b7a2018-05-26 02:46:217338 ChromeTestExtensionLoader(profile()).LoadExtension(
rdevlin.cronin07f10c12017-02-08 19:37:587339 data_dir().AppendASCII("api_test/shared_module/import_pass"));
7340 ASSERT_TRUE(shared_module);
7341 ASSERT_TRUE(dependent);
7342 const std::string kExtensionId = shared_module->id();
Devlin Cronineea1b7a2018-05-26 02:46:217343 ASSERT_TRUE(Manifest::IsUnpackedLocation(shared_module->location()));
7344 ASSERT_EQ(Manifest::TYPE_SHARED_MODULE, shared_module->manifest()->type());
rdevlin.cronin07f10c12017-02-08 19:37:587345 EXPECT_TRUE(registry()->enabled_extensions().Contains(kExtensionId));
7346
7347 // Reload the extension and wait for it to complete. This previously crashed
7348 // (see crbug.com/676815).
7349 service()->ReloadExtension(kExtensionId);
Gabriel Charette01507a22017-09-27 21:30:087350 content::RunAllTasksUntilIdle();
rdevlin.cronin07f10c12017-02-08 19:37:587351 // The shared module should be enabled.
7352 EXPECT_TRUE(registry()->enabled_extensions().Contains(kExtensionId));
7353}
Takumi Fujimoto43c8c00f2017-07-26 22:48:567354
7355// Tests that extensions that have been migrated to component extensions can be
7356// uninstalled.
7357TEST_F(ExtensionServiceTest, UninstallMigratedExtensions) {
7358 InitializeEmptyExtensionService();
7359
7360 scoped_refptr<const Extension> cast_extension =
Devlin Cronin05b047d2017-08-22 21:53:557361 ExtensionBuilder("stable")
7362 .SetID(cast_stable)
7363 .SetLocation(Manifest::INTERNAL)
7364 .Build();
Takumi Fujimoto43c8c00f2017-07-26 22:48:567365 scoped_refptr<const Extension> cast_beta_extension =
Devlin Cronin05b047d2017-08-22 21:53:557366 ExtensionBuilder("beta")
7367 .SetID(cast_beta)
7368 .SetLocation(Manifest::INTERNAL)
7369 .Build();
Takumi Fujimoto43c8c00f2017-07-26 22:48:567370 service()->AddExtension(cast_extension.get());
7371 service()->AddExtension(cast_beta_extension.get());
7372 ASSERT_TRUE(registry()->enabled_extensions().Contains(cast_stable));
7373 ASSERT_TRUE(registry()->enabled_extensions().Contains(cast_beta));
7374
7375 service()->UninstallMigratedExtensionsForTest();
7376 EXPECT_FALSE(service()->GetInstalledExtension(cast_stable));
7377 EXPECT_FALSE(service()->GetInstalledExtension(cast_beta));
7378}
7379
7380// Tests that extensions that have been migrated to component extensions can be
7381// uninstalled even when they are disabled.
7382TEST_F(ExtensionServiceTest, UninstallDisabledMigratedExtension) {
7383 InitializeEmptyExtensionService();
7384
7385 scoped_refptr<const Extension> cast_extension =
Devlin Cronin05b047d2017-08-22 21:53:557386 ExtensionBuilder("stable")
7387 .SetID(cast_stable)
7388 .SetLocation(Manifest::INTERNAL)
7389 .Build();
Takumi Fujimoto43c8c00f2017-07-26 22:48:567390 service()->AddExtension(cast_extension.get());
Devlin Cronineea1b7a2018-05-26 02:46:217391 service()->DisableExtension(cast_stable, disable_reason::DISABLE_USER_ACTION);
Takumi Fujimoto43c8c00f2017-07-26 22:48:567392 ASSERT_TRUE(registry()->disabled_extensions().Contains(cast_stable));
7393
7394 service()->UninstallMigratedExtensionsForTest();
7395 EXPECT_FALSE(service()->GetInstalledExtension(cast_stable));
7396}
Tatsuhisa Yamaguchi5ed1aece32017-10-26 10:18:567397
Devlin Croninae9baf562018-11-15 22:10:047398// Tests the case of a user installing a non-policy extension (e.g. through the
7399// webstore), and that extension later becoming required by policy.
7400// Regression test for https://crbug.com/894184.
7401TEST_F(ExtensionServiceTest, UserInstalledExtensionThenRequiredByPolicy) {
7402 InitializeEmptyExtensionServiceWithTestingPrefs();
7403
7404 // Install an extension as if the user did it.
7405 base::FilePath path = data_dir().AppendASCII("good.crx");
7406 const Extension* extension = InstallCRX(path, INSTALL_NEW);
7407 ASSERT_TRUE(extension);
7408 EXPECT_EQ(good_crx, extension->id());
7409 EXPECT_EQ(Manifest::INTERNAL, extension->location());
7410
7411 std::string kVersionStr = "1.0.0.0";
7412 EXPECT_EQ(kVersionStr, extension->VersionString());
7413
7414 {
7415 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
7416 // Mark good.crx for force-installation.
7417 pref.SetIndividualExtensionAutoInstalled(
7418 good_crx, "http://example.com/update_url", true);
7419 }
7420
7421 // Require good.crx by policy.
7422 MockExternalProvider* provider =
7423 AddMockExternalProvider(Manifest::EXTERNAL_POLICY_DOWNLOAD);
7424 // TODO(devlin): Do we also need to check installing extensions with different
7425 // versions?
7426 provider->UpdateOrAddExtension(good_crx, kVersionStr,
7427 data_dir().AppendASCII("good.crx"));
7428 service()->CheckForExternalUpdates();
7429
7430 ExtensionManagement* management =
7431 ExtensionManagementFactory::GetForBrowserContext(profile());
7432 ExtensionManagement::InstallationMode installation_mode =
7433 management->GetInstallationMode(extension);
7434 EXPECT_EQ(ExtensionManagement::INSTALLATION_FORCED, installation_mode);
7435
7436 // Reload all extensions.
7437 service()->ReloadExtensionsForTest();
7438
7439 extension = registry()->GetInstalledExtension(good_crx);
7440 ASSERT_TRUE(extension);
7441 ManagementPolicy* policy =
7442 ExtensionSystem::Get(browser_context())->management_policy();
7443 // The extension should still be installed, and should be required to
7444 // remain installed.
7445 EXPECT_TRUE(policy->MustRemainInstalled(extension, nullptr));
7446 // TODO(devlin): This currently doesn't work, because the extension is still
7447 // installed with Manifest::Location INTERNAL.
7448 // EXPECT_FALSE(policy->UserMayModifySettings(extension, nullptr));
7449
7450 EXPECT_TRUE(registry()->enabled_extensions().GetByID(good_crx));
7451 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
7452 EXPECT_EQ(disable_reason::DISABLE_NONE, prefs->GetDisableReasons(good_crx));
7453 EXPECT_FALSE(prefs->IsExtensionDisabled(good_crx));
7454}
7455
Karandeep Bhatiad9953e82019-04-05 22:19:257456// Regression test for crbug.com/460699. Ensure PluginManager doesn't crash even
7457// if OnExtensionUnloaded is invoked twice in succession.
7458TEST_F(ExtensionServiceTest, PluginManagerCrash) {
7459 InitializeEmptyExtensionService();
7460 PluginManager manager(profile());
7461
7462 // Load an extension using a NaCl module.
7463 const Extension* extension =
7464 PackAndInstallCRX(data_dir().AppendASCII("native_client"), INSTALL_NEW);
7465 service()->DisableExtension(extension->id(),
7466 disable_reason::DISABLE_USER_ACTION);
7467
7468 // crbug.com/708230: This will cause OnExtensionUnloaded to be called
7469 // redundantly for a disabled extension.
7470 service()->BlockAllExtensions();
7471}
7472
Devlin Cronin2b3acda2019-05-30 19:11:377473class ExternalExtensionPriorityTest
7474 : public ExtensionServiceTest,
7475 public testing::WithParamInterface<Manifest::Location> {};
7476
Oleg Davydov6541a64f2019-04-17 13:17:337477// Policy-forced extensions should be fetched with FOREGROUND priority,
7478// otherwise they may be throttled (web store sends “noupdate” response to
7479// reduce load), which is OK for updates, but not for a new install. This is
7480// a regression test for problems described in https://crbug.com/904600 and
7481// https://crbug.com/917700.
Devlin Cronin2b3acda2019-05-30 19:11:377482TEST_P(ExternalExtensionPriorityTest, PolicyForegroundFetch) {
Oleg Davydov6541a64f2019-04-17 13:17:337483 ExtensionUpdater::ScopedSkipScheduledCheckForTest skip_scheduled_checks;
7484 ExtensionServiceInitParams params = CreateDefaultInitParams();
7485 params.autoupdate_enabled = true;
7486 InitializeExtensionService(params);
7487
7488 ExtensionDownloaderTestHelper helper;
7489 NullExtensionCache extension_cache;
7490 service()->updater()->SetExtensionDownloaderForTesting(
7491 helper.CreateDownloader());
7492 service()->updater()->SetExtensionCacheForTesting(&extension_cache);
7493 service()->updater()->Start();
7494
7495 GURL update_url(extension_urls::kChromeWebstoreUpdateURL);
7496 service()->OnExternalExtensionUpdateUrlFound(
Devlin Cronin2b3acda2019-05-30 19:11:377497 ExternalInstallInfoUpdateUrl(all_zero /* extension_id */,
7498 "" /* install_parameter */, update_url,
7499 GetParam() /* download_location */,
7500 Extension::NO_FLAGS /* creation_flag */,
7501 true /* mark_acknowledged */),
Oleg Davydov6541a64f2019-04-17 13:17:337502 true /* is_initial_load */);
7503
7504 MockExternalProvider provider(nullptr, Manifest::EXTERNAL_POLICY_DOWNLOAD);
7505 service()->OnExternalProviderReady(&provider);
7506
7507 content::RunAllTasksUntilIdle();
7508
7509 EXPECT_EQ(helper.test_url_loader_factory().NumPending(), 1);
7510 network::TestURLLoaderFactory::PendingRequest* pending_request =
7511 helper.test_url_loader_factory().GetPendingRequest(0);
7512 std::string header;
7513 EXPECT_TRUE(pending_request->request.headers.GetHeader(
7514 "X-Goog-Update-Interactivity", &header));
Devlin Cronin2b3acda2019-05-30 19:11:377515 bool is_high_priority = GetParam() == Manifest::EXTERNAL_POLICY_DOWNLOAD ||
7516 GetParam() == Manifest::EXTERNAL_COMPONENT;
7517 const char* expected_header = is_high_priority ? "fg" : "bg";
7518 EXPECT_EQ(expected_header, header);
Oleg Davydov6541a64f2019-04-17 13:17:337519
7520 // Destroy updater's downloader as it uses |helper|.
7521 service()->updater()->SetExtensionDownloaderForTesting(nullptr);
7522}
7523
Devlin Cronin2b3acda2019-05-30 19:11:377524INSTANTIATE_TEST_SUITE_P(,
7525 ExternalExtensionPriorityTest,
7526 testing::Values(Manifest::EXTERNAL_POLICY_DOWNLOAD,
7527 Manifest::EXTERNAL_COMPONENT,
7528 Manifest::EXTERNAL_PREF_DOWNLOAD));
7529
Devlin Cronineea1b7a2018-05-26 02:46:217530} // namespace extensions