blob: 165d9e189ff7caf56298102d8a2ead8d267bf0fb [file] [log] [blame]
[email protected]59b0e602014-01-30 00:41:241// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]31d8f5f22012-04-02 15:22:082// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]59b0e602014-01-30 00:41:245#include "chrome/browser/extensions/extension_system_impl.h"
[email protected]31d8f5f22012-04-02 15:22:086
[email protected]53603d22012-11-14 08:31:117#include "base/base_switches.h"
[email protected]31d8f5f22012-04-02 15:22:088#include "base/bind.h"
9#include "base/command_line.h"
[email protected]57999812013-02-24 05:40:5210#include "base/files/file_path.h"
[email protected]f83bd432014-05-10 20:44:4011#include "base/memory/weak_ptr.h"
[email protected]8bb62162014-06-23 09:45:5012#include "base/metrics/field_trial.h"
[email protected]ef5a9992014-07-25 21:45:2413#include "base/metrics/histogram.h"
[email protected]f4ebe772013-02-02 00:21:3914#include "base/strings/string_tokenizer.h"
[email protected]31d8f5f22012-04-02 15:22:0815#include "chrome/browser/browser_process.h"
[email protected]31d8f5f22012-04-02 15:22:0816#include "chrome/browser/content_settings/cookie_settings.h"
[email protected]fdd679b2012-11-15 20:49:3917#include "chrome/browser/extensions/blacklist.h"
[email protected]931186e02012-07-20 01:22:0618#include "chrome/browser/extensions/component_loader.h"
[email protected]1b66fdb2013-07-26 09:57:2819#include "chrome/browser/extensions/error_console/error_console.h"
[email protected]31d8f5f22012-04-02 15:22:0820#include "chrome/browser/extensions/extension_error_reporter.h"
[email protected]31d8f5f22012-04-02 15:22:0821#include "chrome/browser/extensions/extension_service.h"
22#include "chrome/browser/extensions/extension_system_factory.h"
[email protected]a7ff4b72013-10-17 20:56:0223#include "chrome/browser/extensions/extension_util.h"
[email protected]b4d3771d2012-11-14 14:44:1024#include "chrome/browser/extensions/extension_warning_badge_service.h"
25#include "chrome/browser/extensions/extension_warning_set.h"
[email protected]ffd2f79e2013-11-14 00:11:4626#include "chrome/browser/extensions/install_verifier.h"
[email protected]d9ede582012-08-14 19:21:3827#include "chrome/browser/extensions/navigation_observer.h"
[email protected]f698c162014-06-13 00:46:2628#include "chrome/browser/extensions/shared_module_service.h"
[email protected]fdd679b2012-11-15 20:49:3929#include "chrome/browser/extensions/standard_management_policy_provider.h"
[email protected]479e3922014-07-30 07:12:5730#include "chrome/browser/extensions/state_store_notification_observer.h"
[email protected]abd4cb22014-05-16 05:22:5631#include "chrome/browser/extensions/updater/manifest_fetch_data.h"
[email protected]31d8f5f22012-04-02 15:22:0832#include "chrome/browser/extensions/user_script_master.h"
33#include "chrome/browser/profiles/profile.h"
34#include "chrome/browser/profiles/profile_manager.h"
[email protected]31d8f5f22012-04-02 15:22:0835#include "chrome/common/chrome_switches.h"
[email protected]d69d7b172012-08-09 04:17:2636#include "chrome/common/chrome_version_info.h"
[email protected]dccba4f82014-05-29 00:52:5637#include "chrome/common/extensions/extension_constants.h"
[email protected]abd4cb22014-05-16 05:22:5638#include "chrome/common/extensions/extension_file_util.h"
[email protected]15d4d2d2013-08-09 06:49:0339#include "chrome/common/extensions/features/feature_channel.h"
[email protected]fd3df7782014-05-08 23:54:2740#include "chrome/common/extensions/manifest_url_handler.h"
[email protected]31d8f5f22012-04-02 15:22:0841#include "content/public/browser/browser_thread.h"
[email protected]24ea7a12013-01-27 23:54:5342#include "content/public/browser/url_data_source.h"
[email protected]fd3df7782014-05-08 23:54:2743#include "extensions/browser/content_verifier.h"
[email protected]f83bd432014-05-10 20:44:4044#include "extensions/browser/content_verifier_delegate.h"
[email protected]34423532013-11-21 18:13:1045#include "extensions/browser/event_router.h"
[email protected]489db0842014-01-22 18:20:0346#include "extensions/browser/extension_pref_store.h"
47#include "extensions/browser/extension_pref_value_map.h"
48#include "extensions/browser/extension_pref_value_map_factory.h"
49#include "extensions/browser/extension_prefs.h"
[email protected]45f5b7d2014-01-22 23:47:1350#include "extensions/browser/extension_registry.h"
[email protected]38427a12013-11-09 17:34:2051#include "extensions/browser/info_map.h"
[email protected]9fe42042013-10-29 21:13:3352#include "extensions/browser/lazy_background_task_queue.h"
[email protected]301116c62013-11-26 10:37:4553#include "extensions/browser/management_policy.h"
[email protected]98b6d942013-11-10 00:34:0754#include "extensions/browser/process_manager.h"
[email protected]aab23102014-02-05 18:57:5555#include "extensions/browser/quota_service.h"
[email protected]45f5b7d2014-01-22 23:47:1356#include "extensions/browser/runtime_data.h"
[email protected]daf3ffda2014-06-25 06:44:5757#include "extensions/browser/state_store.h"
[email protected]836e2982013-05-16 08:07:4258#include "extensions/common/constants.h"
[email protected]e4452d32013-11-15 23:07:4159#include "extensions/common/extension.h"
[email protected]d42c11152013-08-22 19:36:3260#include "extensions/common/manifest.h"
[email protected]abd4cb22014-05-16 05:22:5661#include "net/base/escape.h"
[email protected]31d8f5f22012-04-02 15:22:0862
[email protected]72cefae2014-06-27 22:02:4163#if defined(ENABLE_EXTENSIONS)
64#include "chrome/browser/extensions/unpacked_installer.h"
[email protected]70ae4072014-07-11 01:27:1565#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
[email protected]72cefae2014-06-27 22:02:4166#endif
67
[email protected]9afacd22013-11-13 20:23:3168#if defined(ENABLE_NOTIFICATIONS)
69#include "chrome/browser/notifications/desktop_notification_service.h"
70#include "chrome/browser/notifications/desktop_notification_service_factory.h"
71#include "ui/message_center/notifier_settings.h"
72#endif
73
[email protected]bb121482012-12-08 06:49:3874#if defined(OS_CHROMEOS)
[email protected]6ed2e0c2013-04-09 04:48:1375#include "chrome/browser/app_mode/app_mode_utils.h"
[email protected]1a6436112013-10-09 02:49:5876#include "chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.h"
[email protected]83d82d42014-05-16 02:04:4277#include "chrome/browser/chromeos/login/users/user_manager.h"
[email protected]1a6436112013-10-09 02:49:5878#include "chrome/browser/chromeos/policy/device_local_account.h"
[email protected]8bb62162014-06-23 09:45:5079#include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
[email protected]931d1042013-04-05 17:50:4480#include "chromeos/chromeos_switches.h"
[email protected]c57397a2013-04-18 19:41:1181#include "chromeos/login/login_state.h"
[email protected]2fda9972014-07-23 14:51:5982#include "components/user_manager/user.h"
[email protected]bb121482012-12-08 06:49:3883#endif
84
[email protected]31d8f5f22012-04-02 15:22:0885using content::BrowserThread;
86
[email protected]8bb62162014-06-23 09:45:5087namespace {
88
89const char kContentVerificationExperimentName[] =
90 "ExtensionContentVerification";
91
92} // namespace
93
[email protected]bd306722012-07-11 20:43:5994namespace extensions {
95
[email protected]31d8f5f22012-04-02 15:22:0896//
[email protected]31d8f5f22012-04-02 15:22:0897// ExtensionSystemImpl::Shared
98//
99
100ExtensionSystemImpl::Shared::Shared(Profile* profile)
101 : profile_(profile) {
102}
103
104ExtensionSystemImpl::Shared::~Shared() {
105}
106
107void ExtensionSystemImpl::Shared::InitPrefs() {
[email protected]c4dc5cc2012-11-09 08:48:39108 lazy_background_task_queue_.reset(new LazyBackgroundTaskQueue(profile_));
[email protected]836e2982013-05-16 08:07:42109 event_router_.reset(new EventRouter(profile_, ExtensionPrefs::Get(profile_)));
[email protected]d3bd6072013-07-26 18:32:14110// TODO(yoz): Remove once crbug.com/159265 is fixed.
111#if defined(ENABLE_EXTENSIONS)
[email protected]a690e292012-12-19 19:22:49112 // Two state stores. The latter, which contains declarative rules, must be
113 // loaded immediately so that the rules are ready before we issue network
114 // requests.
[email protected]bd306722012-07-11 20:43:59115 state_store_.reset(new StateStore(
[email protected]90e800c2012-06-12 23:11:00116 profile_,
[email protected]501105b2013-09-26 05:42:02117 profile_->GetPath().AppendASCII(extensions::kStateStoreName),
[email protected]a690e292012-12-19 19:22:49118 true));
[email protected]479e3922014-07-30 07:12:57119 state_store_notification_observer_.reset(
120 new StateStoreNotificationObserver(state_store_.get()));
[email protected]d3bd6072013-07-26 18:32:14121
[email protected]a690e292012-12-19 19:22:49122 rules_store_.reset(new StateStore(
123 profile_,
[email protected]501105b2013-09-26 05:42:02124 profile_->GetPath().AppendASCII(extensions::kRulesStoreName),
[email protected]a690e292012-12-19 19:22:49125 false));
[email protected]cb610dc2012-08-31 17:16:56126
[email protected]836e2982013-05-16 08:07:42127 blacklist_.reset(new Blacklist(ExtensionPrefs::Get(profile_)));
[email protected]fdd679b2012-11-15 20:49:39128
129 standard_management_policy_provider_.reset(
[email protected]836e2982013-05-16 08:07:42130 new StandardManagementPolicyProvider(ExtensionPrefs::Get(profile_)));
[email protected]1a6436112013-10-09 02:49:58131
132#if defined (OS_CHROMEOS)
[email protected]2fda9972014-07-23 14:51:59133 const user_manager::User* user =
134 chromeos::UserManager::Get()->GetActiveUser();
[email protected]1a6436112013-10-09 02:49:58135 policy::DeviceLocalAccount::Type device_local_account_type;
136 if (user && policy::IsDeviceLocalAccountUser(user->email(),
137 &device_local_account_type)) {
138 device_local_account_management_policy_provider_.reset(
139 new chromeos::DeviceLocalAccountManagementPolicyProvider(
140 device_local_account_type));
141 }
142#endif // defined (OS_CHROMEOS)
143
144#endif // defined(ENABLE_EXTENSIONS)
[email protected]31d8f5f22012-04-02 15:22:08145}
146
[email protected]65187152012-06-02 13:14:14147void ExtensionSystemImpl::Shared::RegisterManagementPolicyProviders() {
[email protected]d3bd6072013-07-26 18:32:14148// TODO(yoz): Remove once crbug.com/159265 is fixed.
149#if defined(ENABLE_EXTENSIONS)
[email protected]fdd679b2012-11-15 20:49:39150 DCHECK(standard_management_policy_provider_.get());
151 management_policy_->RegisterProvider(
152 standard_management_policy_provider_.get());
[email protected]1a6436112013-10-09 02:49:58153
154#if defined (OS_CHROMEOS)
155 if (device_local_account_management_policy_provider_) {
156 management_policy_->RegisterProvider(
157 device_local_account_management_policy_provider_.get());
158 }
159#endif // defined (OS_CHROMEOS)
160
[email protected]ffd2f79e2013-11-14 00:11:46161 management_policy_->RegisterProvider(install_verifier_.get());
162
[email protected]1a6436112013-10-09 02:49:58163#endif // defined(ENABLE_EXTENSIONS)
[email protected]65187152012-06-02 13:14:14164}
165
[email protected]f83bd432014-05-10 20:44:40166namespace {
167
168class ContentVerifierDelegateImpl : public ContentVerifierDelegate {
169 public:
170 explicit ContentVerifierDelegateImpl(ExtensionService* service)
[email protected]8bb62162014-06-23 09:45:50171 : service_(service->AsWeakPtr()), default_mode_(GetDefaultMode()) {}
[email protected]f83bd432014-05-10 20:44:40172
173 virtual ~ContentVerifierDelegateImpl() {}
174
[email protected]8bb62162014-06-23 09:45:50175 virtual Mode ShouldBeVerified(const Extension& extension) OVERRIDE {
176#if defined(OS_CHROMEOS)
177 if (ExtensionAssetsManagerChromeOS::IsSharedInstall(&extension))
178 return ContentVerifierDelegate::ENFORCE_STRICT;
179#endif
180
[email protected]abd4cb22014-05-16 05:22:56181 if (!extension.is_extension() && !extension.is_legacy_packaged_app())
[email protected]8bb62162014-06-23 09:45:50182 return ContentVerifierDelegate::NONE;
[email protected]abd4cb22014-05-16 05:22:56183 if (!Manifest::IsAutoUpdateableLocation(extension.location()))
[email protected]8bb62162014-06-23 09:45:50184 return ContentVerifierDelegate::NONE;
[email protected]abd4cb22014-05-16 05:22:56185
186 if (!ManifestURL::UpdatesFromGallery(&extension)) {
187 // It's possible that the webstore update url was overridden for testing
188 // so also consider extensions with the default (production) update url
189 // to be from the store as well.
190 GURL default_webstore_url = extension_urls::GetDefaultWebstoreUpdateUrl();
191 if (ManifestURL::GetUpdateURL(&extension) != default_webstore_url)
[email protected]8bb62162014-06-23 09:45:50192 return ContentVerifierDelegate::NONE;
[email protected]abd4cb22014-05-16 05:22:56193 }
194
[email protected]8bb62162014-06-23 09:45:50195 return default_mode_;
[email protected]f83bd432014-05-10 20:44:40196 }
197
198 virtual const ContentVerifierKey& PublicKey() OVERRIDE {
199 static ContentVerifierKey key(
200 extension_misc::kWebstoreSignaturesPublicKey,
201 extension_misc::kWebstoreSignaturesPublicKeySize);
202 return key;
203 }
204
205 virtual GURL GetSignatureFetchUrl(const std::string& extension_id,
206 const base::Version& version) OVERRIDE {
[email protected]abd4cb22014-05-16 05:22:56207 // TODO(asargent) Factor out common code from the extension updater's
208 // ManifestFetchData class that can be shared for use here.
209 std::vector<std::string> parts;
210 parts.push_back("uc");
211 parts.push_back("installsource=signature");
212 parts.push_back("id=" + extension_id);
213 parts.push_back("v=" + version.GetString());
214 std::string x_value =
215 net::EscapeQueryParamValue(JoinString(parts, "&"), true);
216 std::string query = "response=redirect&x=" + x_value;
217
218 GURL base_url = extension_urls::GetWebstoreUpdateUrl();
219 GURL::Replacements replacements;
220 replacements.SetQuery(query.c_str(), url::Component(0, query.length()));
221 return base_url.ReplaceComponents(replacements);
222 }
223
224 virtual std::set<base::FilePath> GetBrowserImagePaths(
225 const extensions::Extension* extension) OVERRIDE {
226 return extension_file_util::GetBrowserImagePaths(extension);
[email protected]f83bd432014-05-10 20:44:40227 }
228
229 virtual void VerifyFailed(const std::string& extension_id) OVERRIDE {
[email protected]6a5898e2014-07-22 23:33:54230 if (!service_)
231 return;
232 ExtensionRegistry* registry = ExtensionRegistry::Get(service_->profile());
233 const Extension* extension =
[email protected]ef5a9992014-07-25 21:45:24234 registry->GetExtensionById(extension_id, ExtensionRegistry::ENABLED);
[email protected]6a5898e2014-07-22 23:33:54235 if (!extension)
236 return;
237 Mode mode = ShouldBeVerified(*extension);
[email protected]ef5a9992014-07-25 21:45:24238 if (mode >= ContentVerifierDelegate::ENFORCE) {
[email protected]f83bd432014-05-10 20:44:40239 service_->DisableExtension(extension_id, Extension::DISABLE_CORRUPTED);
[email protected]ef5a9992014-07-25 21:45:24240 ExtensionPrefs::Get(service_->profile())
241 ->IncrementCorruptedDisableCount();
242 UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionBecameDisabled", true);
243 } else if (!ContainsKey(would_be_disabled_ids_, extension_id)) {
244 UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionWouldBeDisabled", true);
245 would_be_disabled_ids_.insert(extension_id);
246 }
[email protected]f83bd432014-05-10 20:44:40247 }
248
[email protected]8bb62162014-06-23 09:45:50249 static Mode GetDefaultMode() {
250 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
251
252 Mode experiment_value = NONE;
253 const std::string group = base::FieldTrialList::FindFullName(
254 kContentVerificationExperimentName);
255 if (group == "EnforceStrict")
256 experiment_value = ContentVerifierDelegate::ENFORCE_STRICT;
257 else if (group == "Enforce")
258 experiment_value = ContentVerifierDelegate::ENFORCE;
259 else if (group == "Bootstrap")
260 experiment_value = ContentVerifierDelegate::BOOTSTRAP;
261
262 // The field trial value that normally comes from the server can be
263 // overridden on the command line, which we don't want to allow since
264 // malware can set chrome command line flags. There isn't currently a way
265 // to find out what the server-provided value is in this case, so we
266 // conservatively default to the strictest mode if we detect our experiment
267 // name being overridden.
268 if (command_line->HasSwitch(switches::kForceFieldTrials)) {
269 std::string forced_trials =
270 command_line->GetSwitchValueASCII(switches::kForceFieldTrials);
271 if (forced_trials.find(kContentVerificationExperimentName) !=
272 std::string::npos)
273 experiment_value = ContentVerifierDelegate::ENFORCE_STRICT;
274 }
275
276 Mode cmdline_value = NONE;
277 if (command_line->HasSwitch(switches::kExtensionContentVerification)) {
278 std::string switch_value = command_line->GetSwitchValueASCII(
279 switches::kExtensionContentVerification);
280 if (switch_value == switches::kExtensionContentVerificationBootstrap)
281 cmdline_value = ContentVerifierDelegate::BOOTSTRAP;
282 else if (switch_value == switches::kExtensionContentVerificationEnforce)
283 cmdline_value = ContentVerifierDelegate::ENFORCE;
284 else if (switch_value ==
285 switches::kExtensionContentVerificationEnforceStrict)
286 cmdline_value = ContentVerifierDelegate::ENFORCE_STRICT;
287 else
288 // If no value was provided (or the wrong one), just default to enforce.
289 cmdline_value = ContentVerifierDelegate::ENFORCE;
290 }
291
292 // We don't want to allow the command-line flags to eg disable enforcement
293 // if the experiment group says it should be on, or malware may just modify
294 // the command line flags. So return the more restrictive of the 2 values.
295 return std::max(experiment_value, cmdline_value);
296 }
297
[email protected]f83bd432014-05-10 20:44:40298 private:
299 base::WeakPtr<ExtensionService> service_;
[email protected]8bb62162014-06-23 09:45:50300 ContentVerifierDelegate::Mode default_mode_;
[email protected]ef5a9992014-07-25 21:45:24301
302 // For reporting metrics in BOOTSTRAP mode, when an extension would be
303 // disabled if content verification was in ENFORCE mode.
304 std::set<std::string> would_be_disabled_ids_;
305
[email protected]f83bd432014-05-10 20:44:40306 DISALLOW_COPY_AND_ASSIGN(ContentVerifierDelegateImpl);
307};
308
309} // namespace
[email protected]fd3df7782014-05-08 23:54:27310
[email protected]31d8f5f22012-04-02 15:22:08311void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) {
312 const CommandLine* command_line = CommandLine::ForCurrentProcess();
313
[email protected]d9ede582012-08-14 19:21:38314 navigation_observer_.reset(new NavigationObserver(profile_));
[email protected]31d8f5f22012-04-02 15:22:08315
[email protected]53603d22012-11-14 08:31:11316 bool allow_noisy_errors = !command_line->HasSwitch(switches::kNoErrorDialogs);
317 ExtensionErrorReporter::Init(allow_noisy_errors);
[email protected]31d8f5f22012-04-02 15:22:08318
[email protected]4b7d21a52014-07-10 17:07:58319 user_script_master_.reset(new UserScriptMaster(profile_));
[email protected]31d8f5f22012-04-02 15:22:08320
[email protected]45f5b7d2014-01-22 23:47:13321 // ExtensionService depends on RuntimeData.
322 runtime_data_.reset(new RuntimeData(ExtensionRegistry::Get(profile_)));
323
[email protected]acb3f662014-02-18 19:07:10324 bool autoupdate_enabled = !profile_->IsGuestSession();
[email protected]31d8f5f22012-04-02 15:22:08325#if defined(OS_CHROMEOS)
326 if (!extensions_enabled)
327 autoupdate_enabled = false;
[email protected]31d8f5f22012-04-02 15:22:08328#endif
329 extension_service_.reset(new ExtensionService(
330 profile_,
331 CommandLine::ForCurrentProcess(),
[email protected]836e2982013-05-16 08:07:42332 profile_->GetPath().AppendASCII(extensions::kInstallDirectoryName),
333 ExtensionPrefs::Get(profile_),
[email protected]fdd679b2012-11-15 20:49:39334 blacklist_.get(),
[email protected]31d8f5f22012-04-02 15:22:08335 autoupdate_enabled,
[email protected]4a10006a2013-05-17 23:18:35336 extensions_enabled,
337 &ready_));
[email protected]31d8f5f22012-04-02 15:22:08338
[email protected]d7fbc092012-06-18 22:52:00339 // These services must be registered before the ExtensionService tries to
340 // load any extensions.
341 {
[email protected]913ffca92014-03-27 15:26:16342 install_verifier_.reset(
343 new InstallVerifier(ExtensionPrefs::Get(profile_), profile_));
[email protected]ffd2f79e2013-11-14 00:11:46344 install_verifier_->Init();
[email protected]f83bd432014-05-10 20:44:40345 content_verifier_ = new ContentVerifier(
346 profile_, new ContentVerifierDelegateImpl(extension_service_.get()));
[email protected]8bb62162014-06-23 09:45:50347 ContentVerifierDelegate::Mode mode =
348 ContentVerifierDelegateImpl::GetDefaultMode();
349#if defined(OS_CHROMEOS)
350 mode = std::max(mode, ContentVerifierDelegate::BOOTSTRAP);
351#endif
[email protected]6a5898e2014-07-22 23:33:54352 if (mode >= ContentVerifierDelegate::BOOTSTRAP)
[email protected]8bb62162014-06-23 09:45:50353 content_verifier_->Start();
[email protected]fd3df7782014-05-08 23:54:27354 info_map()->SetContentVerifier(content_verifier_.get());
[email protected]ffd2f79e2013-11-14 00:11:46355
[email protected]bd306722012-07-11 20:43:59356 management_policy_.reset(new ManagementPolicy);
[email protected]d7fbc092012-06-18 22:52:00357 RegisterManagementPolicyProviders();
358 }
[email protected]65187152012-06-02 13:14:14359
[email protected]bb121482012-12-08 06:49:38360 bool skip_session_extensions = false;
361#if defined(OS_CHROMEOS)
362 // Skip loading session extensions if we are not in a user session.
[email protected]c57397a2013-04-18 19:41:11363 skip_session_extensions = !chromeos::LoginState::Get()->IsUserLoggedIn();
[email protected]531593d2014-01-08 18:48:31364 if (chrome::IsRunningInForcedAppMode()) {
365 extension_service_->component_loader()->
366 AddDefaultComponentExtensionsForKioskMode(skip_session_extensions);
367 } else {
[email protected]6ed2e0c2013-04-09 04:48:13368 extension_service_->component_loader()->AddDefaultComponentExtensions(
369 skip_session_extensions);
370 }
371#else
[email protected]bb121482012-12-08 06:49:38372 extension_service_->component_loader()->AddDefaultComponentExtensions(
373 skip_session_extensions);
[email protected]6ed2e0c2013-04-09 04:48:13374#endif
[email protected]31d8f5f22012-04-02 15:22:08375 if (command_line->HasSwitch(switches::kLoadComponentExtension)) {
376 CommandLine::StringType path_list = command_line->GetSwitchValueNative(
377 switches::kLoadComponentExtension);
[email protected]f4ebe772013-02-02 00:21:39378 base::StringTokenizerT<CommandLine::StringType,
[email protected]31d8f5f22012-04-02 15:22:08379 CommandLine::StringType::const_iterator> t(path_list,
380 FILE_PATH_LITERAL(","));
381 while (t.GetNext()) {
382 // Load the component extension manifest synchronously.
383 // Blocking the UI thread is acceptable here since
384 // this flag designated for developers.
385 base::ThreadRestrictions::ScopedAllowIO allow_io;
386 extension_service_->component_loader()->AddOrReplace(
[email protected]650b2d52013-02-10 03:41:45387 base::FilePath(t.token()));
[email protected]31d8f5f22012-04-02 15:22:08388 }
389 }
390 extension_service_->Init();
391
[email protected]70ae4072014-07-11 01:27:15392#if defined(ENABLE_EXTENSIONS)
[email protected]c1909afb2013-11-13 21:12:51393 // Make the chrome://extension-icon/ resource available.
394 content::URLDataSource::Add(profile_, new ExtensionIconSource(profile_));
[email protected]70ae4072014-07-11 01:27:15395#endif
[email protected]c1909afb2013-11-13 21:12:51396
397 extension_warning_service_.reset(new ExtensionWarningService(profile_));
398 extension_warning_badge_service_.reset(
399 new ExtensionWarningBadgeService(profile_));
400 extension_warning_service_->AddObserver(
401 extension_warning_badge_service_.get());
[email protected]0659dc92014-04-01 19:23:37402 error_console_.reset(new ErrorConsole(profile_));
[email protected]aab23102014-02-05 18:57:55403 quota_service_.reset(new QuotaService);
[email protected]c1909afb2013-11-13 21:12:51404
[email protected]72cefae2014-06-27 22:02:41405// TODO(thestig): Remove this once ExtensionSystemImpl is no longer built on
406// platforms that do not support extensions.
407#if defined(ENABLE_EXTENSIONS)
[email protected]31d8f5f22012-04-02 15:22:08408 if (extensions_enabled) {
409 // Load any extensions specified with --load-extension.
410 // TODO(yoz): Seems like this should move into ExtensionService::Init.
411 // But maybe it's no longer important.
412 if (command_line->HasSwitch(switches::kLoadExtension)) {
413 CommandLine::StringType path_list = command_line->GetSwitchValueNative(
414 switches::kLoadExtension);
[email protected]f4ebe772013-02-02 00:21:39415 base::StringTokenizerT<CommandLine::StringType,
[email protected]31d8f5f22012-04-02 15:22:08416 CommandLine::StringType::const_iterator> t(path_list,
[email protected]dd6d36672013-05-17 22:50:02417 FILE_PATH_LITERAL(","));
[email protected]31d8f5f22012-04-02 15:22:08418 while (t.GetNext()) {
[email protected]2a69b942013-05-31 09:37:53419 std::string extension_id;
[email protected]98270432012-09-11 20:51:24420 UnpackedInstaller::Create(extension_service_.get())->
[email protected]2a69b942013-05-31 09:37:53421 LoadFromCommandLine(base::FilePath(t.token()), &extension_id);
[email protected]31d8f5f22012-04-02 15:22:08422 }
423 }
424 }
[email protected]72cefae2014-06-27 22:02:41425#endif
[email protected]31d8f5f22012-04-02 15:22:08426}
427
[email protected]47b896562012-08-22 23:55:15428void ExtensionSystemImpl::Shared::Shutdown() {
[email protected]3eeddd892013-04-17 17:00:11429 if (extension_warning_service_) {
[email protected]2def34cd2012-12-08 07:07:54430 extension_warning_service_->RemoveObserver(
431 extension_warning_badge_service_.get());
432 }
[email protected]f83bd432014-05-10 20:44:40433 if (content_verifier_)
[email protected]fd3df7782014-05-08 23:54:27434 content_verifier_->Shutdown();
[email protected]3eeddd892013-04-17 17:00:11435 if (extension_service_)
[email protected]47b896562012-08-22 23:55:15436 extension_service_->Shutdown();
437}
438
[email protected]bd306722012-07-11 20:43:59439StateStore* ExtensionSystemImpl::Shared::state_store() {
[email protected]90e800c2012-06-12 23:11:00440 return state_store_.get();
441}
442
[email protected]a690e292012-12-19 19:22:49443StateStore* ExtensionSystemImpl::Shared::rules_store() {
444 return rules_store_.get();
445}
446
[email protected]31d8f5f22012-04-02 15:22:08447ExtensionService* ExtensionSystemImpl::Shared::extension_service() {
448 return extension_service_.get();
449}
450
[email protected]45f5b7d2014-01-22 23:47:13451RuntimeData* ExtensionSystemImpl::Shared::runtime_data() {
452 return runtime_data_.get();
453}
454
[email protected]bd306722012-07-11 20:43:59455ManagementPolicy* ExtensionSystemImpl::Shared::management_policy() {
[email protected]65187152012-06-02 13:14:14456 return management_policy_.get();
457}
458
[email protected]31d8f5f22012-04-02 15:22:08459UserScriptMaster* ExtensionSystemImpl::Shared::user_script_master() {
460 return user_script_master_.get();
461}
462
[email protected]38427a12013-11-09 17:34:20463InfoMap* ExtensionSystemImpl::Shared::info_map() {
[email protected]dc24976f2013-06-02 21:15:09464 if (!extension_info_map_.get())
[email protected]38427a12013-11-09 17:34:20465 extension_info_map_ = new InfoMap();
[email protected]31d8f5f22012-04-02 15:22:08466 return extension_info_map_.get();
467}
468
[email protected]bd306722012-07-11 20:43:59469LazyBackgroundTaskQueue*
470 ExtensionSystemImpl::Shared::lazy_background_task_queue() {
[email protected]31d8f5f22012-04-02 15:22:08471 return lazy_background_task_queue_.get();
472}
473
[email protected]5a38dfd2012-07-23 23:22:10474EventRouter* ExtensionSystemImpl::Shared::event_router() {
[email protected]c4dc5cc2012-11-09 08:48:39475 return event_router_.get();
[email protected]31d8f5f22012-04-02 15:22:08476}
477
[email protected]2def34cd2012-12-08 07:07:54478ExtensionWarningService* ExtensionSystemImpl::Shared::warning_service() {
479 return extension_warning_service_.get();
480}
481
[email protected]fdd679b2012-11-15 20:49:39482Blacklist* ExtensionSystemImpl::Shared::blacklist() {
483 return blacklist_.get();
484}
485
[email protected]1b66fdb2013-07-26 09:57:28486ErrorConsole* ExtensionSystemImpl::Shared::error_console() {
487 return error_console_.get();
488}
489
[email protected]ffd2f79e2013-11-14 00:11:46490InstallVerifier* ExtensionSystemImpl::Shared::install_verifier() {
491 return install_verifier_.get();
492}
493
[email protected]aab23102014-02-05 18:57:55494QuotaService* ExtensionSystemImpl::Shared::quota_service() {
495 return quota_service_.get();
496}
497
[email protected]fd3df7782014-05-08 23:54:27498ContentVerifier* ExtensionSystemImpl::Shared::content_verifier() {
499 return content_verifier_.get();
500}
501
[email protected]31d8f5f22012-04-02 15:22:08502//
503// ExtensionSystemImpl
504//
505
506ExtensionSystemImpl::ExtensionSystemImpl(Profile* profile)
[email protected]98b673032012-12-11 10:26:02507 : profile_(profile) {
[email protected]59b0e602014-01-30 00:41:24508 shared_ = ExtensionSystemSharedFactory::GetForBrowserContext(profile);
[email protected]31d8f5f22012-04-02 15:22:08509
510 if (profile->IsOffTheRecord()) {
[email protected]98b6d942013-11-10 00:34:07511 process_manager_.reset(ProcessManager::Create(profile));
[email protected]31d8f5f22012-04-02 15:22:08512 } else {
513 shared_->InitPrefs();
514 }
515}
516
517ExtensionSystemImpl::~ExtensionSystemImpl() {
518}
519
520void ExtensionSystemImpl::Shutdown() {
[email protected]98b6d942013-11-10 00:34:07521 process_manager_.reset();
[email protected]31d8f5f22012-04-02 15:22:08522}
523
[email protected]7cf1ee42013-12-11 09:13:49524void ExtensionSystemImpl::InitForRegularProfile(bool extensions_enabled) {
[email protected]31d8f5f22012-04-02 15:22:08525 DCHECK(!profile_->IsOffTheRecord());
526 if (user_script_master() || extension_service())
527 return; // Already initialized.
528
[email protected]98b6d942013-11-10 00:34:07529 // The InfoMap needs to be created before the ProcessManager.
[email protected]9656bc52012-08-13 17:05:33530 shared_->info_map();
[email protected]31d8f5f22012-04-02 15:22:08531
[email protected]98b6d942013-11-10 00:34:07532 process_manager_.reset(ProcessManager::Create(profile_));
[email protected]931186e02012-07-20 01:22:06533
[email protected]31d8f5f22012-04-02 15:22:08534 shared_->Init(extensions_enabled);
535}
536
537ExtensionService* ExtensionSystemImpl::extension_service() {
538 return shared_->extension_service();
539}
540
[email protected]45f5b7d2014-01-22 23:47:13541RuntimeData* ExtensionSystemImpl::runtime_data() {
542 return shared_->runtime_data();
543}
544
[email protected]bd306722012-07-11 20:43:59545ManagementPolicy* ExtensionSystemImpl::management_policy() {
[email protected]65187152012-06-02 13:14:14546 return shared_->management_policy();
547}
548
[email protected]31d8f5f22012-04-02 15:22:08549UserScriptMaster* ExtensionSystemImpl::user_script_master() {
550 return shared_->user_script_master();
551}
552
[email protected]98b6d942013-11-10 00:34:07553ProcessManager* ExtensionSystemImpl::process_manager() {
554 return process_manager_.get();
[email protected]31d8f5f22012-04-02 15:22:08555}
556
[email protected]bd306722012-07-11 20:43:59557StateStore* ExtensionSystemImpl::state_store() {
[email protected]90e800c2012-06-12 23:11:00558 return shared_->state_store();
559}
560
[email protected]a690e292012-12-19 19:22:49561StateStore* ExtensionSystemImpl::rules_store() {
562 return shared_->rules_store();
563}
564
[email protected]38427a12013-11-09 17:34:20565InfoMap* ExtensionSystemImpl::info_map() { return shared_->info_map(); }
[email protected]31d8f5f22012-04-02 15:22:08566
[email protected]bd306722012-07-11 20:43:59567LazyBackgroundTaskQueue* ExtensionSystemImpl::lazy_background_task_queue() {
[email protected]31d8f5f22012-04-02 15:22:08568 return shared_->lazy_background_task_queue();
569}
570
[email protected]5a38dfd2012-07-23 23:22:10571EventRouter* ExtensionSystemImpl::event_router() {
[email protected]31d8f5f22012-04-02 15:22:08572 return shared_->event_router();
573}
574
[email protected]b4d3771d2012-11-14 14:44:10575ExtensionWarningService* ExtensionSystemImpl::warning_service() {
[email protected]2def34cd2012-12-08 07:07:54576 return shared_->warning_service();
[email protected]b4d3771d2012-11-14 14:44:10577}
578
[email protected]fdd679b2012-11-15 20:49:39579Blacklist* ExtensionSystemImpl::blacklist() {
580 return shared_->blacklist();
581}
582
[email protected]4a10006a2013-05-17 23:18:35583const OneShotEvent& ExtensionSystemImpl::ready() const {
584 return shared_->ready();
585}
586
[email protected]1b66fdb2013-07-26 09:57:28587ErrorConsole* ExtensionSystemImpl::error_console() {
588 return shared_->error_console();
589}
590
[email protected]ffd2f79e2013-11-14 00:11:46591InstallVerifier* ExtensionSystemImpl::install_verifier() {
592 return shared_->install_verifier();
593}
594
[email protected]aab23102014-02-05 18:57:55595QuotaService* ExtensionSystemImpl::quota_service() {
596 return shared_->quota_service();
597}
598
[email protected]fd3df7782014-05-08 23:54:27599ContentVerifier* ExtensionSystemImpl::content_verifier() {
600 return shared_->content_verifier();
601}
602
[email protected]f698c162014-06-13 00:46:26603scoped_ptr<ExtensionSet> ExtensionSystemImpl::GetDependentExtensions(
604 const Extension* extension) {
605 return extension_service()->shared_module_service()->GetDependentExtensions(
606 extension);
607}
608
[email protected]31d8f5f22012-04-02 15:22:08609void ExtensionSystemImpl::RegisterExtensionWithRequestContexts(
[email protected]bd306722012-07-11 20:43:59610 const Extension* extension) {
[email protected]31d8f5f22012-04-02 15:22:08611 base::Time install_time;
[email protected]1d5e58b2013-01-31 08:41:40612 if (extension->location() != Manifest::COMPONENT) {
[email protected]836e2982013-05-16 08:07:42613 install_time = ExtensionPrefs::Get(profile_)->
[email protected]31d8f5f22012-04-02 15:22:08614 GetInstallTime(extension->id());
615 }
[email protected]1d5cf4142014-01-24 18:25:22616 bool incognito_enabled = util::IsIncognitoEnabled(extension->id(), profile_);
[email protected]9afacd22013-11-13 20:23:31617
618 bool notifications_disabled = false;
619#if defined(ENABLE_NOTIFICATIONS)
620 message_center::NotifierId notifier_id(
621 message_center::NotifierId::APPLICATION,
622 extension->id());
623
624 DesktopNotificationService* notification_service =
625 DesktopNotificationServiceFactory::GetForProfile(profile_);
626 notifications_disabled =
627 !notification_service->IsNotifierEnabled(notifier_id);
628#endif
629
630 BrowserThread::PostTask(
631 BrowserThread::IO, FROM_HERE,
632 base::Bind(&InfoMap::AddExtension, info_map(),
633 make_scoped_refptr(extension), install_time,
634 incognito_enabled, notifications_disabled));
[email protected]31d8f5f22012-04-02 15:22:08635}
636
637void ExtensionSystemImpl::UnregisterExtensionWithRequestContexts(
638 const std::string& extension_id,
[email protected]b0af4792013-10-23 09:12:13639 const UnloadedExtensionInfo::Reason reason) {
[email protected]31d8f5f22012-04-02 15:22:08640 BrowserThread::PostTask(
[email protected]38427a12013-11-09 17:34:20641 BrowserThread::IO,
642 FROM_HERE,
643 base::Bind(&InfoMap::RemoveExtension, info_map(), extension_id, reason));
[email protected]31d8f5f22012-04-02 15:22:08644}
[email protected]bd306722012-07-11 20:43:59645
646} // namespace extensions