blob: 8e801ca8fb03445e8f616439ed6a64d5e0471e3d [file] [log] [blame]
binjin5f405ef2014-09-03 21:23:161// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/extension_management.h"
6
binjin81d7c552014-10-02 11:47:127#include <algorithm>
binjin81d7c552014-10-02 11:47:128
binjin1569c9b2014-09-05 13:33:189#include "base/bind.h"
10#include "base/bind_helpers.h"
binjin5f405ef2014-09-03 21:23:1611#include "base/logging.h"
rkaplowdd66a1342015-03-05 00:31:4912#include "base/metrics/histogram_macros.h"
binjin5f405ef2014-09-03 21:23:1613#include "base/prefs/pref_service.h"
binjine6b58b52014-10-31 01:55:5714#include "base/strings/string16.h"
binjinb2454382014-09-22 15:17:4315#include "base/strings/string_util.h"
rkaplowdd66a1342015-03-05 00:31:4916#include "base/trace_event/trace_event.h"
binjin8e3d0182014-12-04 16:44:2817#include "base/version.h"
binjinb2454382014-09-22 15:17:4318#include "chrome/browser/extensions/extension_management_constants.h"
binjin81d7c552014-10-02 11:47:1219#include "chrome/browser/extensions/extension_management_internal.h"
binjin30301062014-09-08 20:27:3420#include "chrome/browser/extensions/external_policy_loader.h"
binjin5f405ef2014-09-03 21:23:1621#include "chrome/browser/extensions/external_provider_impl.h"
binjine6b58b52014-10-31 01:55:5722#include "chrome/browser/extensions/permissions_based_management_policy_provider.h"
binjin1569c9b2014-09-05 13:33:1823#include "chrome/browser/extensions/standard_management_policy_provider.h"
binjin9733df12014-09-08 15:21:2124#include "chrome/browser/profiles/incognito_helpers.h"
binjin1569c9b2014-09-05 13:33:1825#include "chrome/browser/profiles/profile.h"
binjin5f405ef2014-09-03 21:23:1626#include "components/crx_file/id_util.h"
binjin1569c9b2014-09-05 13:33:1827#include "components/keyed_service/content/browser_context_dependency_manager.h"
binjinb2454382014-09-22 15:17:4328#include "components/pref_registry/pref_registry_syncable.h"
binjin5f405ef2014-09-03 21:23:1629#include "extensions/browser/pref_names.h"
binjin685ade82014-11-06 09:53:5630#include "extensions/common/manifest_constants.h"
binjine6b58b52014-10-31 01:55:5731#include "extensions/common/permissions/api_permission_set.h"
32#include "extensions/common/permissions/permission_set.h"
binjin5f405ef2014-09-03 21:23:1633#include "extensions/common/url_pattern.h"
binjin311ecdf2014-09-12 22:56:5234#include "url/gurl.h"
binjin5f405ef2014-09-03 21:23:1635
36namespace extensions {
37
binjin5f405ef2014-09-03 21:23:1638ExtensionManagement::ExtensionManagement(PrefService* pref_service)
39 : pref_service_(pref_service) {
rkaplowdd66a1342015-03-05 00:31:4940 TRACE_EVENT0("browser,startup",
41 "ExtensionManagement::ExtensionManagement::ctor");
binjin1569c9b2014-09-05 13:33:1842 pref_change_registrar_.Init(pref_service_);
43 base::Closure pref_change_callback = base::Bind(
44 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this));
45 pref_change_registrar_.Add(pref_names::kInstallAllowList,
46 pref_change_callback);
47 pref_change_registrar_.Add(pref_names::kInstallDenyList,
48 pref_change_callback);
49 pref_change_registrar_.Add(pref_names::kInstallForceList,
50 pref_change_callback);
51 pref_change_registrar_.Add(pref_names::kAllowedInstallSites,
52 pref_change_callback);
53 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback);
binjinb2454382014-09-22 15:17:4354 pref_change_registrar_.Add(pref_names::kExtensionManagement,
55 pref_change_callback);
binjin81d7c552014-10-02 11:47:1256 // Note that both |global_settings_| and |default_settings_| will be null
57 // before first call to Refresh(), so in order to resolve this, Refresh() must
58 // be called in the initialization of ExtensionManagement.
binjin1569c9b2014-09-05 13:33:1859 Refresh();
binjine6b58b52014-10-31 01:55:5760 providers_.push_back(new StandardManagementPolicyProvider(this));
61 providers_.push_back(new PermissionsBasedManagementPolicyProvider(this));
binjin5f405ef2014-09-03 21:23:1662}
63
64ExtensionManagement::~ExtensionManagement() {
65}
66
binjine6b58b52014-10-31 01:55:5767void ExtensionManagement::Shutdown() {
68 pref_change_registrar_.RemoveAll();
69 pref_service_ = nullptr;
70}
71
binjin1569c9b2014-09-05 13:33:1872void ExtensionManagement::AddObserver(Observer* observer) {
73 observer_list_.AddObserver(observer);
74}
75
76void ExtensionManagement::RemoveObserver(Observer* observer) {
77 observer_list_.RemoveObserver(observer);
78}
79
binjine6b58b52014-10-31 01:55:5780std::vector<ManagementPolicy::Provider*> ExtensionManagement::GetProviders()
81 const {
82 return providers_.get();
binjin1569c9b2014-09-05 13:33:1883}
84
binjin81d7c552014-10-02 11:47:1285bool ExtensionManagement::BlacklistedByDefault() const {
86 return default_settings_->installation_mode == INSTALLATION_BLOCKED;
87}
88
89ExtensionManagement::InstallationMode ExtensionManagement::GetInstallationMode(
binjin685ade82014-11-06 09:53:5690 const Extension* extension) const {
91 // Check per-extension installation mode setting first.
92 auto iter_id = settings_by_id_.find(extension->id());
93 if (iter_id != settings_by_id_.end())
94 return iter_id->second->installation_mode;
95 std::string update_url;
96 // Check per-update-url installation mode setting.
97 if (extension->manifest()->GetString(manifest_keys::kUpdateURL,
98 &update_url)) {
99 auto iter_update_url = settings_by_update_url_.find(update_url);
100 if (iter_update_url != settings_by_update_url_.end())
101 return iter_update_url->second->installation_mode;
102 }
103 // Fall back to default installation mode setting.
104 return default_settings_->installation_mode;
binjin1569c9b2014-09-05 13:33:18105}
106
binjin30301062014-09-08 20:27:34107scoped_ptr<base::DictionaryValue> ExtensionManagement::GetForceInstallList()
108 const {
binjincccacef2014-10-13 19:00:20109 scoped_ptr<base::DictionaryValue> install_list(new base::DictionaryValue());
binjin30301062014-09-08 20:27:34110 for (SettingsIdMap::const_iterator it = settings_by_id_.begin();
111 it != settings_by_id_.end();
112 ++it) {
binjin81d7c552014-10-02 11:47:12113 if (it->second->installation_mode == INSTALLATION_FORCED) {
binjin30301062014-09-08 20:27:34114 ExternalPolicyLoader::AddExtension(
binjincccacef2014-10-13 19:00:20115 install_list.get(), it->first, it->second->update_url);
binjin30301062014-09-08 20:27:34116 }
117 }
binjincccacef2014-10-13 19:00:20118 return install_list.Pass();
119}
120
121scoped_ptr<base::DictionaryValue>
122ExtensionManagement::GetRecommendedInstallList() const {
123 scoped_ptr<base::DictionaryValue> install_list(new base::DictionaryValue());
124 for (SettingsIdMap::const_iterator it = settings_by_id_.begin();
125 it != settings_by_id_.end();
126 ++it) {
127 if (it->second->installation_mode == INSTALLATION_RECOMMENDED) {
128 ExternalPolicyLoader::AddExtension(
129 install_list.get(), it->first, it->second->update_url);
130 }
131 }
132 return install_list.Pass();
binjin30301062014-09-08 20:27:34133}
134
binjinc641add2014-10-15 16:20:45135bool ExtensionManagement::IsInstallationExplicitlyAllowed(
136 const ExtensionId& id) const {
137 SettingsIdMap::const_iterator it = settings_by_id_.find(id);
138 // No settings explicitly specified for |id|.
139 if (it == settings_by_id_.end())
140 return false;
141 // Checks if the extension is on the automatically installed list or
142 // install white-list.
143 InstallationMode mode = it->second->installation_mode;
144 return mode == INSTALLATION_FORCED || mode == INSTALLATION_RECOMMENDED ||
145 mode == INSTALLATION_ALLOWED;
binjin30301062014-09-08 20:27:34146}
147
binjin81d7c552014-10-02 11:47:12148bool ExtensionManagement::IsOffstoreInstallAllowed(
149 const GURL& url,
150 const GURL& referrer_url) const {
binjin311ecdf2014-09-12 22:56:52151 // No allowed install sites specified, disallow by default.
binjin81d7c552014-10-02 11:47:12152 if (!global_settings_->has_restricted_install_sources)
binjin311ecdf2014-09-12 22:56:52153 return false;
154
binjin81d7c552014-10-02 11:47:12155 const URLPatternSet& url_patterns = global_settings_->install_sources;
binjin311ecdf2014-09-12 22:56:52156
157 if (!url_patterns.MatchesURL(url))
158 return false;
159
160 // The referrer URL must also be whitelisted, unless the URL has the file
161 // scheme (there's no referrer for those URLs).
162 return url.SchemeIsFile() || url_patterns.MatchesURL(referrer_url);
163}
164
binjin81d7c552014-10-02 11:47:12165bool ExtensionManagement::IsAllowedManifestType(
166 Manifest::Type manifest_type) const {
167 if (!global_settings_->has_restricted_allowed_types)
168 return true;
169 const std::vector<Manifest::Type>& allowed_types =
170 global_settings_->allowed_types;
171 return std::find(allowed_types.begin(), allowed_types.end(), manifest_type) !=
172 allowed_types.end();
binjin1569c9b2014-09-05 13:33:18173}
174
binjin685ade82014-11-06 09:53:56175APIPermissionSet ExtensionManagement::GetBlockedAPIPermissions(
176 const Extension* extension) const {
177 // Fetch per-extension blocked permissions setting.
178 auto iter_id = settings_by_id_.find(extension->id());
179
180 // Fetch per-update-url blocked permissions setting.
181 std::string update_url;
182 auto iter_update_url = settings_by_update_url_.end();
183 if (extension->manifest()->GetString(manifest_keys::kUpdateURL,
184 &update_url)) {
185 iter_update_url = settings_by_update_url_.find(update_url);
186 }
187
188 if (iter_id != settings_by_id_.end() &&
189 iter_update_url != settings_by_update_url_.end()) {
190 // Blocked permissions setting are specified in both per-extension and
191 // per-update-url settings, try to merge them.
192 APIPermissionSet merged;
193 APIPermissionSet::Union(iter_id->second->blocked_permissions,
194 iter_update_url->second->blocked_permissions,
195 &merged);
196 return merged;
197 }
198 // Check whether if in one of them, setting is specified.
199 if (iter_id != settings_by_id_.end())
200 return iter_id->second->blocked_permissions;
201 if (iter_update_url != settings_by_update_url_.end())
202 return iter_update_url->second->blocked_permissions;
203 // Fall back to the default blocked permissions setting.
204 return default_settings_->blocked_permissions;
binjine6b58b52014-10-31 01:55:57205}
206
207scoped_refptr<const PermissionSet> ExtensionManagement::GetBlockedPermissions(
binjin685ade82014-11-06 09:53:56208 const Extension* extension) const {
binjine6b58b52014-10-31 01:55:57209 // Only api permissions are supported currently.
binjin685ade82014-11-06 09:53:56210 return scoped_refptr<const PermissionSet>(new PermissionSet(
211 GetBlockedAPIPermissions(extension), ManifestPermissionSet(),
212 URLPatternSet(), URLPatternSet()));
binjine6b58b52014-10-31 01:55:57213}
214
215bool ExtensionManagement::IsPermissionSetAllowed(
binjin685ade82014-11-06 09:53:56216 const Extension* extension,
binjine6b58b52014-10-31 01:55:57217 scoped_refptr<const PermissionSet> perms) const {
binjin685ade82014-11-06 09:53:56218 for (const auto& blocked_api : GetBlockedAPIPermissions(extension)) {
binjine6b58b52014-10-31 01:55:57219 if (perms->HasAPIPermission(blocked_api->id()))
220 return false;
221 }
222 return true;
223}
224
binjin8e3d0182014-12-04 16:44:28225bool ExtensionManagement::CheckMinimumVersion(
226 const Extension* extension,
227 std::string* required_version) const {
228 auto iter = settings_by_id_.find(extension->id());
229 // If there are no minimum version required for |extension|, return true.
230 if (iter == settings_by_id_.end() || !iter->second->minimum_version_required)
231 return true;
232 bool meets_requirement = extension->version()->CompareTo(
233 *iter->second->minimum_version_required) >= 0;
234 // Output a human readable version string for prompting if necessary.
235 if (!meets_requirement && required_version)
236 *required_version = iter->second->minimum_version_required->GetString();
237 return meets_requirement;
238}
239
binjin5f405ef2014-09-03 21:23:16240void ExtensionManagement::Refresh() {
rkaplowdd66a1342015-03-05 00:31:49241 TRACE_EVENT0("browser,startup", "ExtensionManagement::Refresh");
242 SCOPED_UMA_HISTOGRAM_TIMER("Extensions.ExtensionManagement_RefreshTime");
binjin5f405ef2014-09-03 21:23:16243 // Load all extension management settings preferences.
244 const base::ListValue* allowed_list_pref =
245 static_cast<const base::ListValue*>(LoadPreference(
246 pref_names::kInstallAllowList, true, base::Value::TYPE_LIST));
247 // Allow user to use preference to block certain extensions. Note that policy
248 // managed forcelist or whitelist will always override this.
249 const base::ListValue* denied_list_pref =
250 static_cast<const base::ListValue*>(LoadPreference(
251 pref_names::kInstallDenyList, false, base::Value::TYPE_LIST));
252 const base::DictionaryValue* forced_list_pref =
253 static_cast<const base::DictionaryValue*>(LoadPreference(
254 pref_names::kInstallForceList, true, base::Value::TYPE_DICTIONARY));
255 const base::ListValue* install_sources_pref =
256 static_cast<const base::ListValue*>(LoadPreference(
257 pref_names::kAllowedInstallSites, true, base::Value::TYPE_LIST));
258 const base::ListValue* allowed_types_pref =
259 static_cast<const base::ListValue*>(LoadPreference(
260 pref_names::kAllowedTypes, true, base::Value::TYPE_LIST));
binjinb2454382014-09-22 15:17:43261 const base::DictionaryValue* dict_pref =
262 static_cast<const base::DictionaryValue*>(
263 LoadPreference(pref_names::kExtensionManagement,
264 true,
265 base::Value::TYPE_DICTIONARY));
binjin5f405ef2014-09-03 21:23:16266
267 // Reset all settings.
binjin81d7c552014-10-02 11:47:12268 global_settings_.reset(new internal::GlobalSettings());
binjin5f405ef2014-09-03 21:23:16269 settings_by_id_.clear();
binjin81d7c552014-10-02 11:47:12270 default_settings_.reset(new internal::IndividualSettings());
binjin5f405ef2014-09-03 21:23:16271
272 // Parse default settings.
273 const base::StringValue wildcard("*");
274 if (denied_list_pref &&
275 denied_list_pref->Find(wildcard) != denied_list_pref->end()) {
binjin81d7c552014-10-02 11:47:12276 default_settings_->installation_mode = INSTALLATION_BLOCKED;
binjin5f405ef2014-09-03 21:23:16277 }
278
binjinb2454382014-09-22 15:17:43279 const base::DictionaryValue* subdict = NULL;
280 if (dict_pref &&
281 dict_pref->GetDictionary(schema_constants::kWildcard, &subdict)) {
binjin81d7c552014-10-02 11:47:12282 if (!default_settings_->Parse(
283 subdict, internal::IndividualSettings::SCOPE_DEFAULT)) {
binjinb2454382014-09-22 15:17:43284 LOG(WARNING) << "Default extension management settings parsing error.";
binjin81d7c552014-10-02 11:47:12285 default_settings_->Reset();
binjinb2454382014-09-22 15:17:43286 }
287
288 // Settings from new preference have higher priority over legacy ones.
289 const base::ListValue* list_value = NULL;
290 if (subdict->GetList(schema_constants::kInstallSources, &list_value))
291 install_sources_pref = list_value;
292 if (subdict->GetList(schema_constants::kAllowedTypes, &list_value))
293 allowed_types_pref = list_value;
294 }
295
binjin5f405ef2014-09-03 21:23:16296 // Parse legacy preferences.
297 ExtensionId id;
298
299 if (allowed_list_pref) {
300 for (base::ListValue::const_iterator it = allowed_list_pref->begin();
301 it != allowed_list_pref->end(); ++it) {
302 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id))
303 AccessById(id)->installation_mode = INSTALLATION_ALLOWED;
304 }
305 }
306
307 if (denied_list_pref) {
308 for (base::ListValue::const_iterator it = denied_list_pref->begin();
309 it != denied_list_pref->end(); ++it) {
310 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id))
311 AccessById(id)->installation_mode = INSTALLATION_BLOCKED;
312 }
313 }
314
315 if (forced_list_pref) {
316 std::string update_url;
317 for (base::DictionaryValue::Iterator it(*forced_list_pref); !it.IsAtEnd();
318 it.Advance()) {
319 if (!crx_file::id_util::IdIsValid(it.key()))
320 continue;
321 const base::DictionaryValue* dict_value = NULL;
322 if (it.value().GetAsDictionary(&dict_value) &&
323 dict_value->GetStringWithoutPathExpansion(
324 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) {
binjin81d7c552014-10-02 11:47:12325 internal::IndividualSettings* by_id = AccessById(it.key());
binjin5f405ef2014-09-03 21:23:16326 by_id->installation_mode = INSTALLATION_FORCED;
327 by_id->update_url = update_url;
328 }
329 }
330 }
331
332 if (install_sources_pref) {
binjin81d7c552014-10-02 11:47:12333 global_settings_->has_restricted_install_sources = true;
binjin5f405ef2014-09-03 21:23:16334 for (base::ListValue::const_iterator it = install_sources_pref->begin();
335 it != install_sources_pref->end(); ++it) {
binjinb2454382014-09-22 15:17:43336 std::string url_pattern;
binjin5f405ef2014-09-03 21:23:16337 if ((*it)->GetAsString(&url_pattern)) {
binjinb2454382014-09-22 15:17:43338 URLPattern entry(URLPattern::SCHEME_ALL);
binjin5f405ef2014-09-03 21:23:16339 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) {
binjin81d7c552014-10-02 11:47:12340 global_settings_->install_sources.AddPattern(entry);
binjin5f405ef2014-09-03 21:23:16341 } else {
342 LOG(WARNING) << "Invalid URL pattern in for preference "
343 << pref_names::kAllowedInstallSites << ": "
344 << url_pattern << ".";
345 }
346 }
347 }
348 }
349
350 if (allowed_types_pref) {
binjin81d7c552014-10-02 11:47:12351 global_settings_->has_restricted_allowed_types = true;
binjin5f405ef2014-09-03 21:23:16352 for (base::ListValue::const_iterator it = allowed_types_pref->begin();
353 it != allowed_types_pref->end(); ++it) {
354 int int_value;
binjinb2454382014-09-22 15:17:43355 std::string string_value;
binjin5f405ef2014-09-03 21:23:16356 if ((*it)->GetAsInteger(&int_value) && int_value >= 0 &&
357 int_value < Manifest::Type::NUM_LOAD_TYPES) {
binjin81d7c552014-10-02 11:47:12358 global_settings_->allowed_types.push_back(
binjin5f405ef2014-09-03 21:23:16359 static_cast<Manifest::Type>(int_value));
binjinb2454382014-09-22 15:17:43360 } else if ((*it)->GetAsString(&string_value)) {
361 Manifest::Type manifest_type =
362 schema_constants::GetManifestType(string_value);
363 if (manifest_type != Manifest::TYPE_UNKNOWN)
binjin81d7c552014-10-02 11:47:12364 global_settings_->allowed_types.push_back(manifest_type);
binjin5f405ef2014-09-03 21:23:16365 }
366 }
367 }
368
binjinb2454382014-09-22 15:17:43369 if (dict_pref) {
370 // Parse new extension management preference.
371 for (base::DictionaryValue::Iterator iter(*dict_pref); !iter.IsAtEnd();
372 iter.Advance()) {
373 if (iter.key() == schema_constants::kWildcard)
374 continue;
binjin81d7c552014-10-02 11:47:12375 if (!iter.value().GetAsDictionary(&subdict))
binjinb2454382014-09-22 15:17:43376 continue;
brettw66d1b81b2015-07-06 19:29:40377 if (base::StartsWith(iter.key(), schema_constants::kUpdateUrlPrefix,
378 base::CompareCase::SENSITIVE)) {
binjin685ade82014-11-06 09:53:56379 const std::string& update_url =
380 iter.key().substr(strlen(schema_constants::kUpdateUrlPrefix));
381 if (!GURL(update_url).is_valid()) {
382 LOG(WARNING) << "Invalid update URL: " << update_url << ".";
383 continue;
384 }
385 internal::IndividualSettings* by_update_url =
386 AccessByUpdateUrl(update_url);
387 if (!by_update_url->Parse(
388 subdict, internal::IndividualSettings::SCOPE_UPDATE_URL)) {
389 settings_by_update_url_.erase(update_url);
390 LOG(WARNING) << "Malformed Extension Management settings for "
391 "extensions with update url: " << update_url << ".";
392 }
393 } else {
394 const std::string& extension_id = iter.key();
395 if (!crx_file::id_util::IdIsValid(extension_id)) {
396 LOG(WARNING) << "Invalid extension ID : " << extension_id << ".";
397 continue;
398 }
399 internal::IndividualSettings* by_id = AccessById(extension_id);
400 if (!by_id->Parse(subdict,
401 internal::IndividualSettings::SCOPE_INDIVIDUAL)) {
402 settings_by_id_.erase(extension_id);
403 LOG(WARNING) << "Malformed Extension Management settings for "
404 << extension_id << ".";
405 }
binjinb2454382014-09-22 15:17:43406 }
407 }
408 }
binjin5f405ef2014-09-03 21:23:16409}
410
binjin5f405ef2014-09-03 21:23:16411const base::Value* ExtensionManagement::LoadPreference(
412 const char* pref_name,
413 bool force_managed,
414 base::Value::Type expected_type) {
binjine6b58b52014-10-31 01:55:57415 if (!pref_service_)
416 return nullptr;
binjin5f405ef2014-09-03 21:23:16417 const PrefService::Preference* pref =
418 pref_service_->FindPreference(pref_name);
419 if (pref && !pref->IsDefaultValue() &&
420 (!force_managed || pref->IsManaged())) {
421 const base::Value* value = pref->GetValue();
422 if (value && value->IsType(expected_type))
423 return value;
424 }
binjine6b58b52014-10-31 01:55:57425 return nullptr;
binjin5f405ef2014-09-03 21:23:16426}
427
binjin1569c9b2014-09-05 13:33:18428void ExtensionManagement::OnExtensionPrefChanged() {
429 Refresh();
430 NotifyExtensionManagementPrefChanged();
431}
432
433void ExtensionManagement::NotifyExtensionManagementPrefChanged() {
434 FOR_EACH_OBSERVER(
435 Observer, observer_list_, OnExtensionManagementSettingsChanged());
436}
437
binjin81d7c552014-10-02 11:47:12438internal::IndividualSettings* ExtensionManagement::AccessById(
binjin5f405ef2014-09-03 21:23:16439 const ExtensionId& id) {
440 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id;
441 SettingsIdMap::iterator it = settings_by_id_.find(id);
binjin81d7c552014-10-02 11:47:12442 if (it == settings_by_id_.end()) {
443 scoped_ptr<internal::IndividualSettings> settings(
binjin8e3d0182014-12-04 16:44:28444 new internal::IndividualSettings(default_settings_.get()));
binjin81d7c552014-10-02 11:47:12445 it = settings_by_id_.add(id, settings.Pass()).first;
446 }
447 return it->second;
binjin5f405ef2014-09-03 21:23:16448}
449
binjin685ade82014-11-06 09:53:56450internal::IndividualSettings* ExtensionManagement::AccessByUpdateUrl(
451 const std::string& update_url) {
452 DCHECK(GURL(update_url).is_valid()) << "Invalid update URL: " << update_url;
453 SettingsUpdateUrlMap::iterator it = settings_by_update_url_.find(update_url);
454 if (it == settings_by_update_url_.end()) {
455 scoped_ptr<internal::IndividualSettings> settings(
binjin8e3d0182014-12-04 16:44:28456 new internal::IndividualSettings(default_settings_.get()));
binjin685ade82014-11-06 09:53:56457 it = settings_by_update_url_.add(update_url, settings.Pass()).first;
458 }
459 return it->second;
460}
461
binjin1569c9b2014-09-05 13:33:18462ExtensionManagement* ExtensionManagementFactory::GetForBrowserContext(
463 content::BrowserContext* context) {
464 return static_cast<ExtensionManagement*>(
465 GetInstance()->GetServiceForBrowserContext(context, true));
466}
467
468ExtensionManagementFactory* ExtensionManagementFactory::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:22469 return base::Singleton<ExtensionManagementFactory>::get();
binjin1569c9b2014-09-05 13:33:18470}
471
472ExtensionManagementFactory::ExtensionManagementFactory()
473 : BrowserContextKeyedServiceFactory(
474 "ExtensionManagement",
475 BrowserContextDependencyManager::GetInstance()) {
476}
477
478ExtensionManagementFactory::~ExtensionManagementFactory() {
479}
480
481KeyedService* ExtensionManagementFactory::BuildServiceInstanceFor(
482 content::BrowserContext* context) const {
rkaplowdd66a1342015-03-05 00:31:49483 TRACE_EVENT0("browser,startup",
484 "ExtensionManagementFactory::BuildServiceInstanceFor");
binjin1569c9b2014-09-05 13:33:18485 return new ExtensionManagement(
486 Profile::FromBrowserContext(context)->GetPrefs());
487}
488
binjin9733df12014-09-08 15:21:21489content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse(
490 content::BrowserContext* context) const {
491 return chrome::GetBrowserContextRedirectedInIncognito(context);
492}
493
binjinb2454382014-09-22 15:17:43494void ExtensionManagementFactory::RegisterProfilePrefs(
495 user_prefs::PrefRegistrySyncable* user_prefs) {
raymesaa608722015-04-27 03:00:25496 user_prefs->RegisterDictionaryPref(pref_names::kExtensionManagement);
binjinb2454382014-09-22 15:17:43497}
498
binjin5f405ef2014-09-03 21:23:16499} // namespace extensions