blob: d1d5e12b0f6a73a792a8946f3f59a38150e41718 [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]15ad2ee2014-08-15 19:15:2615#include "base/strings/string_util.h"
[email protected]31d8f5f22012-04-02 15:22:0816#include "chrome/browser/browser_process.h"
[email protected]31d8f5f22012-04-02 15:22:0817#include "chrome/browser/content_settings/cookie_settings.h"
[email protected]931186e02012-07-20 01:22:0618#include "chrome/browser/extensions/component_loader.h"
hanxi6d9b43a2014-12-12 21:53:4619#include "chrome/browser/extensions/declarative_user_script_manager.h"
[email protected]1b66fdb2013-07-26 09:57:2820#include "chrome/browser/extensions/error_console/error_console.h"
[email protected]31d8f5f22012-04-02 15:22:0821#include "chrome/browser/extensions/extension_error_reporter.h"
binjin1569c9b2014-09-05 13:33:1822#include "chrome/browser/extensions/extension_management.h"
[email protected]31d8f5f22012-04-02 15:22:0823#include "chrome/browser/extensions/extension_service.h"
24#include "chrome/browser/extensions/extension_system_factory.h"
[email protected]a7ff4b72013-10-17 20:56:0225#include "chrome/browser/extensions/extension_util.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]15ad2ee2014-08-15 19:15:2629#include "chrome/browser/extensions/shared_user_script_master.h"
[email protected]479e3922014-07-30 07:12:5730#include "chrome/browser/extensions/state_store_notification_observer.h"
[email protected]13e062e2014-08-09 10:21:5531#include "chrome/browser/extensions/unpacked_installer.h"
[email protected]31d8f5f22012-04-02 15:22:0832#include "chrome/browser/profiles/profile.h"
33#include "chrome/browser/profiles/profile_manager.h"
[email protected]13e062e2014-08-09 10:21:5534#include "chrome/browser/ui/webui/extensions/extension_icon_source.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]15d4d2d2013-08-09 06:49:0338#include "chrome/common/extensions/features/feature_channel.h"
[email protected]31d8f5f22012-04-02 15:22:0839#include "content/public/browser/browser_thread.h"
[email protected]24ea7a12013-01-27 23:54:5340#include "content/public/browser/url_data_source.h"
[email protected]fd3df7782014-05-08 23:54:2741#include "extensions/browser/content_verifier.h"
[email protected]f83bd432014-05-10 20:44:4042#include "extensions/browser/content_verifier_delegate.h"
[email protected]34423532013-11-21 18:13:1043#include "extensions/browser/event_router.h"
[email protected]489db0842014-01-22 18:20:0344#include "extensions/browser/extension_pref_store.h"
45#include "extensions/browser/extension_pref_value_map.h"
46#include "extensions/browser/extension_pref_value_map_factory.h"
47#include "extensions/browser/extension_prefs.h"
[email protected]45f5b7d2014-01-22 23:47:1348#include "extensions/browser/extension_registry.h"
[email protected]38427a12013-11-09 17:34:2049#include "extensions/browser/info_map.h"
[email protected]9fe42042013-10-29 21:13:3350#include "extensions/browser/lazy_background_task_queue.h"
[email protected]301116c62013-11-26 10:37:4551#include "extensions/browser/management_policy.h"
[email protected]aab23102014-02-05 18:57:5552#include "extensions/browser/quota_service.h"
[email protected]45f5b7d2014-01-22 23:47:1353#include "extensions/browser/runtime_data.h"
[email protected]daf3ffda2014-06-25 06:44:5754#include "extensions/browser/state_store.h"
[email protected]836e2982013-05-16 08:07:4255#include "extensions/common/constants.h"
[email protected]e4452d32013-11-15 23:07:4156#include "extensions/common/extension.h"
rockot90659852014-09-18 19:31:5257#include "extensions/common/extension_urls.h"
rockotec1e64b2014-11-13 22:06:5158#include "extensions/common/extensions_client.h"
[email protected]d42c11152013-08-22 19:36:3259#include "extensions/common/manifest.h"
rockotd5546142014-10-15 00:29:0860#include "extensions/common/manifest_url_handlers.h"
[email protected]abd4cb22014-05-16 05:22:5661#include "net/base/escape.h"
[email protected]31d8f5f22012-04-02 15:22:0862
[email protected]9afacd22013-11-13 20:23:3163#if defined(ENABLE_NOTIFICATIONS)
64#include "chrome/browser/notifications/desktop_notification_service.h"
65#include "chrome/browser/notifications/desktop_notification_service_factory.h"
66#include "ui/message_center/notifier_settings.h"
67#endif
68
[email protected]bb121482012-12-08 06:49:3869#if defined(OS_CHROMEOS)
[email protected]6ed2e0c2013-04-09 04:48:1370#include "chrome/browser/app_mode/app_mode_utils.h"
[email protected]1a6436112013-10-09 02:49:5871#include "chrome/browser/chromeos/extensions/device_local_account_management_policy_provider.h"
[email protected]1a6436112013-10-09 02:49:5872#include "chrome/browser/chromeos/policy/device_local_account.h"
[email protected]8bb62162014-06-23 09:45:5073#include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
[email protected]931d1042013-04-05 17:50:4474#include "chromeos/chromeos_switches.h"
[email protected]c57397a2013-04-18 19:41:1175#include "chromeos/login/login_state.h"
[email protected]2fda9972014-07-23 14:51:5976#include "components/user_manager/user.h"
[email protected]4d390782014-08-15 09:22:5877#include "components/user_manager/user_manager.h"
[email protected]bb121482012-12-08 06:49:3878#endif
79
[email protected]31d8f5f22012-04-02 15:22:0880using content::BrowserThread;
81
[email protected]8bb62162014-06-23 09:45:5082namespace {
83
84const char kContentVerificationExperimentName[] =
85 "ExtensionContentVerification";
86
87} // namespace
88
[email protected]bd306722012-07-11 20:43:5989namespace extensions {
90
[email protected]31d8f5f22012-04-02 15:22:0891//
[email protected]31d8f5f22012-04-02 15:22:0892// ExtensionSystemImpl::Shared
93//
94
95ExtensionSystemImpl::Shared::Shared(Profile* profile)
96 : profile_(profile) {
97}
98
99ExtensionSystemImpl::Shared::~Shared() {
100}
101
102void ExtensionSystemImpl::Shared::InitPrefs() {
[email protected]c4dc5cc2012-11-09 08:48:39103 lazy_background_task_queue_.reset(new LazyBackgroundTaskQueue(profile_));
[email protected]836e2982013-05-16 08:07:42104 event_router_.reset(new EventRouter(profile_, ExtensionPrefs::Get(profile_)));
[email protected]a690e292012-12-19 19:22:49105 // Two state stores. The latter, which contains declarative rules, must be
106 // loaded immediately so that the rules are ready before we issue network
107 // requests.
[email protected]bd306722012-07-11 20:43:59108 state_store_.reset(new StateStore(
[email protected]90e800c2012-06-12 23:11:00109 profile_,
[email protected]501105b2013-09-26 05:42:02110 profile_->GetPath().AppendASCII(extensions::kStateStoreName),
[email protected]a690e292012-12-19 19:22:49111 true));
[email protected]479e3922014-07-30 07:12:57112 state_store_notification_observer_.reset(
113 new StateStoreNotificationObserver(state_store_.get()));
[email protected]d3bd6072013-07-26 18:32:14114
[email protected]a690e292012-12-19 19:22:49115 rules_store_.reset(new StateStore(
116 profile_,
[email protected]501105b2013-09-26 05:42:02117 profile_->GetPath().AppendASCII(extensions::kRulesStoreName),
[email protected]a690e292012-12-19 19:22:49118 false));
[email protected]cb610dc2012-08-31 17:16:56119
[email protected]13e062e2014-08-09 10:21:55120#if defined(OS_CHROMEOS)
[email protected]2fda9972014-07-23 14:51:59121 const user_manager::User* user =
[email protected]4d390782014-08-15 09:22:58122 user_manager::UserManager::Get()->GetActiveUser();
[email protected]1a6436112013-10-09 02:49:58123 policy::DeviceLocalAccount::Type device_local_account_type;
124 if (user && policy::IsDeviceLocalAccountUser(user->email(),
125 &device_local_account_type)) {
126 device_local_account_management_policy_provider_.reset(
127 new chromeos::DeviceLocalAccountManagementPolicyProvider(
128 device_local_account_type));
129 }
[email protected]13e062e2014-08-09 10:21:55130#endif // defined(OS_CHROMEOS)
[email protected]31d8f5f22012-04-02 15:22:08131}
132
[email protected]65187152012-06-02 13:14:14133void ExtensionSystemImpl::Shared::RegisterManagementPolicyProviders() {
binjine6b58b52014-10-31 01:55:57134 management_policy_->RegisterProviders(
binjin1569c9b2014-09-05 13:33:18135 ExtensionManagementFactory::GetForBrowserContext(profile_)
binjine6b58b52014-10-31 01:55:57136 ->GetProviders());
[email protected]1a6436112013-10-09 02:49:58137
[email protected]13e062e2014-08-09 10:21:55138#if defined(OS_CHROMEOS)
[email protected]1a6436112013-10-09 02:49:58139 if (device_local_account_management_policy_provider_) {
140 management_policy_->RegisterProvider(
141 device_local_account_management_policy_provider_.get());
142 }
[email protected]13e062e2014-08-09 10:21:55143#endif // defined(OS_CHROMEOS)
[email protected]1a6436112013-10-09 02:49:58144
[email protected]ffd2f79e2013-11-14 00:11:46145 management_policy_->RegisterProvider(install_verifier_.get());
[email protected]65187152012-06-02 13:14:14146}
147
[email protected]f83bd432014-05-10 20:44:40148namespace {
149
150class ContentVerifierDelegateImpl : public ContentVerifierDelegate {
151 public:
152 explicit ContentVerifierDelegateImpl(ExtensionService* service)
[email protected]8bb62162014-06-23 09:45:50153 : service_(service->AsWeakPtr()), default_mode_(GetDefaultMode()) {}
[email protected]f83bd432014-05-10 20:44:40154
dchengae36a4a2014-10-21 12:36:36155 ~ContentVerifierDelegateImpl() override {}
[email protected]f83bd432014-05-10 20:44:40156
dchengae36a4a2014-10-21 12:36:36157 Mode ShouldBeVerified(const Extension& extension) override {
[email protected]8bb62162014-06-23 09:45:50158#if defined(OS_CHROMEOS)
159 if (ExtensionAssetsManagerChromeOS::IsSharedInstall(&extension))
160 return ContentVerifierDelegate::ENFORCE_STRICT;
161#endif
162
[email protected]abd4cb22014-05-16 05:22:56163 if (!extension.is_extension() && !extension.is_legacy_packaged_app())
[email protected]8bb62162014-06-23 09:45:50164 return ContentVerifierDelegate::NONE;
[email protected]abd4cb22014-05-16 05:22:56165 if (!Manifest::IsAutoUpdateableLocation(extension.location()))
[email protected]8bb62162014-06-23 09:45:50166 return ContentVerifierDelegate::NONE;
[email protected]abd4cb22014-05-16 05:22:56167
168 if (!ManifestURL::UpdatesFromGallery(&extension)) {
169 // It's possible that the webstore update url was overridden for testing
170 // so also consider extensions with the default (production) update url
171 // to be from the store as well.
172 GURL default_webstore_url = extension_urls::GetDefaultWebstoreUpdateUrl();
173 if (ManifestURL::GetUpdateURL(&extension) != default_webstore_url)
[email protected]8bb62162014-06-23 09:45:50174 return ContentVerifierDelegate::NONE;
[email protected]abd4cb22014-05-16 05:22:56175 }
176
[email protected]8bb62162014-06-23 09:45:50177 return default_mode_;
[email protected]f83bd432014-05-10 20:44:40178 }
179
dchengae36a4a2014-10-21 12:36:36180 const ContentVerifierKey& PublicKey() override {
[email protected]f83bd432014-05-10 20:44:40181 static ContentVerifierKey key(
182 extension_misc::kWebstoreSignaturesPublicKey,
183 extension_misc::kWebstoreSignaturesPublicKeySize);
184 return key;
185 }
186
dchengae36a4a2014-10-21 12:36:36187 GURL GetSignatureFetchUrl(const std::string& extension_id,
188 const base::Version& version) override {
[email protected]abd4cb22014-05-16 05:22:56189 // TODO(asargent) Factor out common code from the extension updater's
190 // ManifestFetchData class that can be shared for use here.
191 std::vector<std::string> parts;
192 parts.push_back("uc");
193 parts.push_back("installsource=signature");
194 parts.push_back("id=" + extension_id);
195 parts.push_back("v=" + version.GetString());
196 std::string x_value =
197 net::EscapeQueryParamValue(JoinString(parts, "&"), true);
198 std::string query = "response=redirect&x=" + x_value;
199
200 GURL base_url = extension_urls::GetWebstoreUpdateUrl();
201 GURL::Replacements replacements;
202 replacements.SetQuery(query.c_str(), url::Component(0, query.length()));
203 return base_url.ReplaceComponents(replacements);
204 }
205
dchengae36a4a2014-10-21 12:36:36206 std::set<base::FilePath> GetBrowserImagePaths(
mostynba15bee12014-10-04 00:40:32207 const extensions::Extension* extension) override {
rockotec1e64b2014-11-13 22:06:51208 return ExtensionsClient::Get()->GetBrowserImagePaths(extension);
[email protected]f83bd432014-05-10 20:44:40209 }
210
dchengae36a4a2014-10-21 12:36:36211 void VerifyFailed(const std::string& extension_id,
212 ContentVerifyJob::FailureReason reason) override {
[email protected]6a5898e2014-07-22 23:33:54213 if (!service_)
214 return;
215 ExtensionRegistry* registry = ExtensionRegistry::Get(service_->profile());
216 const Extension* extension =
[email protected]ef5a9992014-07-25 21:45:24217 registry->GetExtensionById(extension_id, ExtensionRegistry::ENABLED);
[email protected]6a5898e2014-07-22 23:33:54218 if (!extension)
219 return;
220 Mode mode = ShouldBeVerified(*extension);
[email protected]ef5a9992014-07-25 21:45:24221 if (mode >= ContentVerifierDelegate::ENFORCE) {
[email protected]f83bd432014-05-10 20:44:40222 service_->DisableExtension(extension_id, Extension::DISABLE_CORRUPTED);
[email protected]ef5a9992014-07-25 21:45:24223 ExtensionPrefs::Get(service_->profile())
224 ->IncrementCorruptedDisableCount();
225 UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionBecameDisabled", true);
rockoteb1491d2014-10-07 03:56:40226 UMA_HISTOGRAM_ENUMERATION("Extensions.CorruptExtensionDisabledReason",
227 reason, ContentVerifyJob::FAILURE_REASON_MAX);
[email protected]ef5a9992014-07-25 21:45:24228 } else if (!ContainsKey(would_be_disabled_ids_, extension_id)) {
229 UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionWouldBeDisabled", true);
230 would_be_disabled_ids_.insert(extension_id);
231 }
[email protected]f83bd432014-05-10 20:44:40232 }
233
[email protected]8bb62162014-06-23 09:45:50234 static Mode GetDefaultMode() {
235 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
236
237 Mode experiment_value = NONE;
238 const std::string group = base::FieldTrialList::FindFullName(
239 kContentVerificationExperimentName);
240 if (group == "EnforceStrict")
241 experiment_value = ContentVerifierDelegate::ENFORCE_STRICT;
242 else if (group == "Enforce")
243 experiment_value = ContentVerifierDelegate::ENFORCE;
244 else if (group == "Bootstrap")
245 experiment_value = ContentVerifierDelegate::BOOTSTRAP;
246
247 // The field trial value that normally comes from the server can be
248 // overridden on the command line, which we don't want to allow since
249 // malware can set chrome command line flags. There isn't currently a way
250 // to find out what the server-provided value is in this case, so we
251 // conservatively default to the strictest mode if we detect our experiment
252 // name being overridden.
253 if (command_line->HasSwitch(switches::kForceFieldTrials)) {
254 std::string forced_trials =
255 command_line->GetSwitchValueASCII(switches::kForceFieldTrials);
256 if (forced_trials.find(kContentVerificationExperimentName) !=
257 std::string::npos)
258 experiment_value = ContentVerifierDelegate::ENFORCE_STRICT;
259 }
260
261 Mode cmdline_value = NONE;
262 if (command_line->HasSwitch(switches::kExtensionContentVerification)) {
263 std::string switch_value = command_line->GetSwitchValueASCII(
264 switches::kExtensionContentVerification);
265 if (switch_value == switches::kExtensionContentVerificationBootstrap)
266 cmdline_value = ContentVerifierDelegate::BOOTSTRAP;
267 else if (switch_value == switches::kExtensionContentVerificationEnforce)
268 cmdline_value = ContentVerifierDelegate::ENFORCE;
269 else if (switch_value ==
270 switches::kExtensionContentVerificationEnforceStrict)
271 cmdline_value = ContentVerifierDelegate::ENFORCE_STRICT;
272 else
273 // If no value was provided (or the wrong one), just default to enforce.
274 cmdline_value = ContentVerifierDelegate::ENFORCE;
275 }
276
277 // We don't want to allow the command-line flags to eg disable enforcement
278 // if the experiment group says it should be on, or malware may just modify
279 // the command line flags. So return the more restrictive of the 2 values.
280 return std::max(experiment_value, cmdline_value);
281 }
282
[email protected]f83bd432014-05-10 20:44:40283 private:
284 base::WeakPtr<ExtensionService> service_;
[email protected]8bb62162014-06-23 09:45:50285 ContentVerifierDelegate::Mode default_mode_;
[email protected]ef5a9992014-07-25 21:45:24286
287 // For reporting metrics in BOOTSTRAP mode, when an extension would be
288 // disabled if content verification was in ENFORCE mode.
289 std::set<std::string> would_be_disabled_ids_;
290
[email protected]f83bd432014-05-10 20:44:40291 DISALLOW_COPY_AND_ASSIGN(ContentVerifierDelegateImpl);
292};
293
294} // namespace
[email protected]fd3df7782014-05-08 23:54:27295
[email protected]31d8f5f22012-04-02 15:22:08296void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) {
avi3ef9ec9e2014-12-22 22:50:17297 const base::CommandLine* command_line =
298 base::CommandLine::ForCurrentProcess();
[email protected]31d8f5f22012-04-02 15:22:08299
[email protected]d9ede582012-08-14 19:21:38300 navigation_observer_.reset(new NavigationObserver(profile_));
[email protected]31d8f5f22012-04-02 15:22:08301
[email protected]53603d22012-11-14 08:31:11302 bool allow_noisy_errors = !command_line->HasSwitch(switches::kNoErrorDialogs);
303 ExtensionErrorReporter::Init(allow_noisy_errors);
[email protected]31d8f5f22012-04-02 15:22:08304
[email protected]15ad2ee2014-08-15 19:15:26305 shared_user_script_master_.reset(new SharedUserScriptMaster(profile_));
hanxi6d9b43a2014-12-12 21:53:46306 declarative_user_script_manager_.reset(
307 new DeclarativeUserScriptManager(profile_));
[email protected]31d8f5f22012-04-02 15:22:08308
[email protected]45f5b7d2014-01-22 23:47:13309 // ExtensionService depends on RuntimeData.
310 runtime_data_.reset(new RuntimeData(ExtensionRegistry::Get(profile_)));
311
[email protected]acb3f662014-02-18 19:07:10312 bool autoupdate_enabled = !profile_->IsGuestSession();
[email protected]31d8f5f22012-04-02 15:22:08313#if defined(OS_CHROMEOS)
314 if (!extensions_enabled)
315 autoupdate_enabled = false;
[email protected]31d8f5f22012-04-02 15:22:08316#endif
317 extension_service_.reset(new ExtensionService(
avi3ef9ec9e2014-12-22 22:50:17318 profile_, base::CommandLine::ForCurrentProcess(),
[email protected]836e2982013-05-16 08:07:42319 profile_->GetPath().AppendASCII(extensions::kInstallDirectoryName),
avi3ef9ec9e2014-12-22 22:50:17320 ExtensionPrefs::Get(profile_), Blacklist::Get(profile_),
321 autoupdate_enabled, extensions_enabled, &ready_));
[email protected]31d8f5f22012-04-02 15:22:08322
[email protected]d7fbc092012-06-18 22:52:00323 // These services must be registered before the ExtensionService tries to
324 // load any extensions.
325 {
[email protected]913ffca92014-03-27 15:26:16326 install_verifier_.reset(
327 new InstallVerifier(ExtensionPrefs::Get(profile_), profile_));
[email protected]ffd2f79e2013-11-14 00:11:46328 install_verifier_->Init();
[email protected]f83bd432014-05-10 20:44:40329 content_verifier_ = new ContentVerifier(
330 profile_, new ContentVerifierDelegateImpl(extension_service_.get()));
[email protected]8bb62162014-06-23 09:45:50331 ContentVerifierDelegate::Mode mode =
332 ContentVerifierDelegateImpl::GetDefaultMode();
333#if defined(OS_CHROMEOS)
334 mode = std::max(mode, ContentVerifierDelegate::BOOTSTRAP);
335#endif
[email protected]6a5898e2014-07-22 23:33:54336 if (mode >= ContentVerifierDelegate::BOOTSTRAP)
[email protected]8bb62162014-06-23 09:45:50337 content_verifier_->Start();
[email protected]fd3df7782014-05-08 23:54:27338 info_map()->SetContentVerifier(content_verifier_.get());
[email protected]ffd2f79e2013-11-14 00:11:46339
[email protected]bd306722012-07-11 20:43:59340 management_policy_.reset(new ManagementPolicy);
[email protected]d7fbc092012-06-18 22:52:00341 RegisterManagementPolicyProviders();
342 }
[email protected]65187152012-06-02 13:14:14343
[email protected]bb121482012-12-08 06:49:38344 bool skip_session_extensions = false;
345#if defined(OS_CHROMEOS)
346 // Skip loading session extensions if we are not in a user session.
[email protected]c57397a2013-04-18 19:41:11347 skip_session_extensions = !chromeos::LoginState::Get()->IsUserLoggedIn();
[email protected]531593d2014-01-08 18:48:31348 if (chrome::IsRunningInForcedAppMode()) {
349 extension_service_->component_loader()->
350 AddDefaultComponentExtensionsForKioskMode(skip_session_extensions);
351 } else {
[email protected]6ed2e0c2013-04-09 04:48:13352 extension_service_->component_loader()->AddDefaultComponentExtensions(
353 skip_session_extensions);
354 }
355#else
[email protected]bb121482012-12-08 06:49:38356 extension_service_->component_loader()->AddDefaultComponentExtensions(
357 skip_session_extensions);
[email protected]6ed2e0c2013-04-09 04:48:13358#endif
[email protected]31d8f5f22012-04-02 15:22:08359 if (command_line->HasSwitch(switches::kLoadComponentExtension)) {
avi3ef9ec9e2014-12-22 22:50:17360 base::CommandLine::StringType path_list =
361 command_line->GetSwitchValueNative(switches::kLoadComponentExtension);
362 base::StringTokenizerT<base::CommandLine::StringType,
363 base::CommandLine::StringType::const_iterator>
364 t(path_list, FILE_PATH_LITERAL(","));
[email protected]31d8f5f22012-04-02 15:22:08365 while (t.GetNext()) {
366 // Load the component extension manifest synchronously.
367 // Blocking the UI thread is acceptable here since
368 // this flag designated for developers.
369 base::ThreadRestrictions::ScopedAllowIO allow_io;
370 extension_service_->component_loader()->AddOrReplace(
[email protected]650b2d52013-02-10 03:41:45371 base::FilePath(t.token()));
[email protected]31d8f5f22012-04-02 15:22:08372 }
373 }
374 extension_service_->Init();
375
[email protected]c1909afb2013-11-13 21:12:51376 // Make the chrome://extension-icon/ resource available.
377 content::URLDataSource::Add(profile_, new ExtensionIconSource(profile_));
378
[email protected]0659dc92014-04-01 19:23:37379 error_console_.reset(new ErrorConsole(profile_));
[email protected]aab23102014-02-05 18:57:55380 quota_service_.reset(new QuotaService);
[email protected]c1909afb2013-11-13 21:12:51381
[email protected]31d8f5f22012-04-02 15:22:08382 if (extensions_enabled) {
383 // Load any extensions specified with --load-extension.
384 // TODO(yoz): Seems like this should move into ExtensionService::Init.
385 // But maybe it's no longer important.
386 if (command_line->HasSwitch(switches::kLoadExtension)) {
avi3ef9ec9e2014-12-22 22:50:17387 base::CommandLine::StringType path_list =
388 command_line->GetSwitchValueNative(switches::kLoadExtension);
389 base::StringTokenizerT<base::CommandLine::StringType,
390 base::CommandLine::StringType::const_iterator>
391 t(path_list, FILE_PATH_LITERAL(","));
[email protected]31d8f5f22012-04-02 15:22:08392 while (t.GetNext()) {
[email protected]2a69b942013-05-31 09:37:53393 std::string extension_id;
[email protected]98270432012-09-11 20:51:24394 UnpackedInstaller::Create(extension_service_.get())->
[email protected]2a69b942013-05-31 09:37:53395 LoadFromCommandLine(base::FilePath(t.token()), &extension_id);
[email protected]31d8f5f22012-04-02 15:22:08396 }
397 }
398 }
[email protected]31d8f5f22012-04-02 15:22:08399}
400
[email protected]47b896562012-08-22 23:55:15401void ExtensionSystemImpl::Shared::Shutdown() {
dchengc7047942014-08-26 05:05:31402 if (content_verifier_.get())
[email protected]fd3df7782014-05-08 23:54:27403 content_verifier_->Shutdown();
[email protected]3eeddd892013-04-17 17:00:11404 if (extension_service_)
[email protected]47b896562012-08-22 23:55:15405 extension_service_->Shutdown();
406}
407
[email protected]bd306722012-07-11 20:43:59408StateStore* ExtensionSystemImpl::Shared::state_store() {
[email protected]90e800c2012-06-12 23:11:00409 return state_store_.get();
410}
411
[email protected]a690e292012-12-19 19:22:49412StateStore* ExtensionSystemImpl::Shared::rules_store() {
413 return rules_store_.get();
414}
415
[email protected]31d8f5f22012-04-02 15:22:08416ExtensionService* ExtensionSystemImpl::Shared::extension_service() {
417 return extension_service_.get();
418}
419
[email protected]45f5b7d2014-01-22 23:47:13420RuntimeData* ExtensionSystemImpl::Shared::runtime_data() {
421 return runtime_data_.get();
422}
423
[email protected]bd306722012-07-11 20:43:59424ManagementPolicy* ExtensionSystemImpl::Shared::management_policy() {
[email protected]65187152012-06-02 13:14:14425 return management_policy_.get();
426}
427
[email protected]15ad2ee2014-08-15 19:15:26428SharedUserScriptMaster*
429ExtensionSystemImpl::Shared::shared_user_script_master() {
430 return shared_user_script_master_.get();
[email protected]31d8f5f22012-04-02 15:22:08431}
432
hanxi6d9b43a2014-12-12 21:53:46433DeclarativeUserScriptManager*
434ExtensionSystemImpl::Shared::declarative_user_script_manager() {
435 return declarative_user_script_manager_.get();
436}
437
[email protected]38427a12013-11-09 17:34:20438InfoMap* ExtensionSystemImpl::Shared::info_map() {
[email protected]dc24976f2013-06-02 21:15:09439 if (!extension_info_map_.get())
[email protected]38427a12013-11-09 17:34:20440 extension_info_map_ = new InfoMap();
[email protected]31d8f5f22012-04-02 15:22:08441 return extension_info_map_.get();
442}
443
[email protected]bd306722012-07-11 20:43:59444LazyBackgroundTaskQueue*
445 ExtensionSystemImpl::Shared::lazy_background_task_queue() {
[email protected]31d8f5f22012-04-02 15:22:08446 return lazy_background_task_queue_.get();
447}
448
[email protected]5a38dfd2012-07-23 23:22:10449EventRouter* ExtensionSystemImpl::Shared::event_router() {
[email protected]c4dc5cc2012-11-09 08:48:39450 return event_router_.get();
[email protected]31d8f5f22012-04-02 15:22:08451}
452
[email protected]1b66fdb2013-07-26 09:57:28453ErrorConsole* ExtensionSystemImpl::Shared::error_console() {
454 return error_console_.get();
455}
456
[email protected]ffd2f79e2013-11-14 00:11:46457InstallVerifier* ExtensionSystemImpl::Shared::install_verifier() {
458 return install_verifier_.get();
459}
460
[email protected]aab23102014-02-05 18:57:55461QuotaService* ExtensionSystemImpl::Shared::quota_service() {
462 return quota_service_.get();
463}
464
[email protected]fd3df7782014-05-08 23:54:27465ContentVerifier* ExtensionSystemImpl::Shared::content_verifier() {
466 return content_verifier_.get();
467}
468
[email protected]31d8f5f22012-04-02 15:22:08469//
470// ExtensionSystemImpl
471//
472
473ExtensionSystemImpl::ExtensionSystemImpl(Profile* profile)
[email protected]98b673032012-12-11 10:26:02474 : profile_(profile) {
[email protected]59b0e602014-01-30 00:41:24475 shared_ = ExtensionSystemSharedFactory::GetForBrowserContext(profile);
[email protected]31d8f5f22012-04-02 15:22:08476
reillyg0ea3fa902014-10-28 15:30:23477 if (!profile->IsOffTheRecord()) {
[email protected]31d8f5f22012-04-02 15:22:08478 shared_->InitPrefs();
479 }
480}
481
482ExtensionSystemImpl::~ExtensionSystemImpl() {
483}
484
485void ExtensionSystemImpl::Shutdown() {
[email protected]31d8f5f22012-04-02 15:22:08486}
487
[email protected]7cf1ee42013-12-11 09:13:49488void ExtensionSystemImpl::InitForRegularProfile(bool extensions_enabled) {
[email protected]31d8f5f22012-04-02 15:22:08489 DCHECK(!profile_->IsOffTheRecord());
[email protected]15ad2ee2014-08-15 19:15:26490 if (shared_user_script_master() || extension_service())
[email protected]31d8f5f22012-04-02 15:22:08491 return; // Already initialized.
492
[email protected]98b6d942013-11-10 00:34:07493 // The InfoMap needs to be created before the ProcessManager.
[email protected]9656bc52012-08-13 17:05:33494 shared_->info_map();
[email protected]31d8f5f22012-04-02 15:22:08495 shared_->Init(extensions_enabled);
496}
497
498ExtensionService* ExtensionSystemImpl::extension_service() {
499 return shared_->extension_service();
500}
501
[email protected]45f5b7d2014-01-22 23:47:13502RuntimeData* ExtensionSystemImpl::runtime_data() {
503 return shared_->runtime_data();
504}
505
[email protected]bd306722012-07-11 20:43:59506ManagementPolicy* ExtensionSystemImpl::management_policy() {
[email protected]65187152012-06-02 13:14:14507 return shared_->management_policy();
508}
509
[email protected]15ad2ee2014-08-15 19:15:26510SharedUserScriptMaster* ExtensionSystemImpl::shared_user_script_master() {
511 return shared_->shared_user_script_master();
[email protected]31d8f5f22012-04-02 15:22:08512}
513
hanxi6d9b43a2014-12-12 21:53:46514DeclarativeUserScriptManager*
515ExtensionSystemImpl::declarative_user_script_manager() {
516 return shared_->declarative_user_script_manager();
517}
518
[email protected]bd306722012-07-11 20:43:59519StateStore* ExtensionSystemImpl::state_store() {
[email protected]90e800c2012-06-12 23:11:00520 return shared_->state_store();
521}
522
[email protected]a690e292012-12-19 19:22:49523StateStore* ExtensionSystemImpl::rules_store() {
524 return shared_->rules_store();
525}
526
[email protected]38427a12013-11-09 17:34:20527InfoMap* ExtensionSystemImpl::info_map() { return shared_->info_map(); }
[email protected]31d8f5f22012-04-02 15:22:08528
[email protected]bd306722012-07-11 20:43:59529LazyBackgroundTaskQueue* ExtensionSystemImpl::lazy_background_task_queue() {
[email protected]31d8f5f22012-04-02 15:22:08530 return shared_->lazy_background_task_queue();
531}
532
[email protected]5a38dfd2012-07-23 23:22:10533EventRouter* ExtensionSystemImpl::event_router() {
[email protected]31d8f5f22012-04-02 15:22:08534 return shared_->event_router();
535}
536
[email protected]4a10006a2013-05-17 23:18:35537const OneShotEvent& ExtensionSystemImpl::ready() const {
538 return shared_->ready();
539}
540
[email protected]1b66fdb2013-07-26 09:57:28541ErrorConsole* ExtensionSystemImpl::error_console() {
542 return shared_->error_console();
543}
544
[email protected]ffd2f79e2013-11-14 00:11:46545InstallVerifier* ExtensionSystemImpl::install_verifier() {
546 return shared_->install_verifier();
547}
548
[email protected]aab23102014-02-05 18:57:55549QuotaService* ExtensionSystemImpl::quota_service() {
550 return shared_->quota_service();
551}
552
[email protected]fd3df7782014-05-08 23:54:27553ContentVerifier* ExtensionSystemImpl::content_verifier() {
554 return shared_->content_verifier();
555}
556
[email protected]f698c162014-06-13 00:46:26557scoped_ptr<ExtensionSet> ExtensionSystemImpl::GetDependentExtensions(
558 const Extension* extension) {
559 return extension_service()->shared_module_service()->GetDependentExtensions(
560 extension);
561}
562
[email protected]31d8f5f22012-04-02 15:22:08563void ExtensionSystemImpl::RegisterExtensionWithRequestContexts(
[email protected]bd306722012-07-11 20:43:59564 const Extension* extension) {
[email protected]31d8f5f22012-04-02 15:22:08565 base::Time install_time;
[email protected]1d5e58b2013-01-31 08:41:40566 if (extension->location() != Manifest::COMPONENT) {
[email protected]836e2982013-05-16 08:07:42567 install_time = ExtensionPrefs::Get(profile_)->
[email protected]31d8f5f22012-04-02 15:22:08568 GetInstallTime(extension->id());
569 }
[email protected]1d5cf4142014-01-24 18:25:22570 bool incognito_enabled = util::IsIncognitoEnabled(extension->id(), profile_);
[email protected]9afacd22013-11-13 20:23:31571
572 bool notifications_disabled = false;
573#if defined(ENABLE_NOTIFICATIONS)
574 message_center::NotifierId notifier_id(
575 message_center::NotifierId::APPLICATION,
576 extension->id());
577
578 DesktopNotificationService* notification_service =
579 DesktopNotificationServiceFactory::GetForProfile(profile_);
580 notifications_disabled =
581 !notification_service->IsNotifierEnabled(notifier_id);
582#endif
583
584 BrowserThread::PostTask(
585 BrowserThread::IO, FROM_HERE,
586 base::Bind(&InfoMap::AddExtension, info_map(),
587 make_scoped_refptr(extension), install_time,
588 incognito_enabled, notifications_disabled));
[email protected]31d8f5f22012-04-02 15:22:08589}
590
591void ExtensionSystemImpl::UnregisterExtensionWithRequestContexts(
592 const std::string& extension_id,
[email protected]b0af4792013-10-23 09:12:13593 const UnloadedExtensionInfo::Reason reason) {
[email protected]31d8f5f22012-04-02 15:22:08594 BrowserThread::PostTask(
[email protected]38427a12013-11-09 17:34:20595 BrowserThread::IO,
596 FROM_HERE,
597 base::Bind(&InfoMap::RemoveExtension, info_map(), extension_id, reason));
[email protected]31d8f5f22012-04-02 15:22:08598}
[email protected]bd306722012-07-11 20:43:59599
600} // namespace extensions