| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_management.h" | 5 #include "chrome/browser/extensions/extension_management.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "components/pref_registry/pref_registry_syncable.h" | 29 #include "components/pref_registry/pref_registry_syncable.h" |
| 30 #include "components/prefs/pref_service.h" | 30 #include "components/prefs/pref_service.h" |
| 31 #include "extensions/browser/pref_names.h" | 31 #include "extensions/browser/pref_names.h" |
| 32 #include "extensions/common/extension.h" | 32 #include "extensions/common/extension.h" |
| 33 #include "extensions/common/manifest_constants.h" | 33 #include "extensions/common/manifest_constants.h" |
| 34 #include "extensions/common/permissions/api_permission_set.h" | 34 #include "extensions/common/permissions/api_permission_set.h" |
| 35 #include "extensions/common/permissions/permission_set.h" | 35 #include "extensions/common/permissions/permission_set.h" |
| 36 #include "extensions/common/url_pattern.h" | 36 #include "extensions/common/url_pattern.h" |
| 37 #include "url/gurl.h" | 37 #include "url/gurl.h" |
| 38 | 38 |
| 39 #if defined(OS_CHROMEOS) |
| 40 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 41 #endif |
| 42 |
| 39 namespace extensions { | 43 namespace extensions { |
| 40 | 44 |
| 41 ExtensionManagement::ExtensionManagement(PrefService* pref_service) | 45 ExtensionManagement::ExtensionManagement(Profile* profile) : profile_(profile) { |
| 42 : pref_service_(pref_service) { | |
| 43 TRACE_EVENT0("browser,startup", | 46 TRACE_EVENT0("browser,startup", |
| 44 "ExtensionManagement::ExtensionManagement::ctor"); | 47 "ExtensionManagement::ExtensionManagement::ctor"); |
| 45 pref_change_registrar_.Init(pref_service_); | 48 pref_change_registrar_.Init(profile_->GetPrefs()); |
| 46 base::Closure pref_change_callback = base::Bind( | 49 base::Closure pref_change_callback = base::Bind( |
| 47 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this)); | 50 &ExtensionManagement::OnExtensionPrefChanged, base::Unretained(this)); |
| 48 pref_change_registrar_.Add(pref_names::kInstallAllowList, | 51 pref_change_registrar_.Add(pref_names::kInstallAllowList, |
| 49 pref_change_callback); | 52 pref_change_callback); |
| 50 pref_change_registrar_.Add(pref_names::kInstallDenyList, | 53 pref_change_registrar_.Add(pref_names::kInstallDenyList, |
| 51 pref_change_callback); | 54 pref_change_callback); |
| 52 pref_change_registrar_.Add(pref_names::kInstallForceList, | 55 pref_change_registrar_.Add(pref_names::kInstallForceList, |
| 53 pref_change_callback); | 56 pref_change_callback); |
| 57 pref_change_registrar_.Add(pref_names::kInstallLoginScreenAppList, |
| 58 pref_change_callback); |
| 54 pref_change_registrar_.Add(pref_names::kAllowedInstallSites, | 59 pref_change_registrar_.Add(pref_names::kAllowedInstallSites, |
| 55 pref_change_callback); | 60 pref_change_callback); |
| 56 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); | 61 pref_change_registrar_.Add(pref_names::kAllowedTypes, pref_change_callback); |
| 57 pref_change_registrar_.Add(pref_names::kExtensionManagement, | 62 pref_change_registrar_.Add(pref_names::kExtensionManagement, |
| 58 pref_change_callback); | 63 pref_change_callback); |
| 59 // Note that both |global_settings_| and |default_settings_| will be null | 64 // Note that both |global_settings_| and |default_settings_| will be null |
| 60 // before first call to Refresh(), so in order to resolve this, Refresh() must | 65 // before first call to Refresh(), so in order to resolve this, Refresh() must |
| 61 // be called in the initialization of ExtensionManagement. | 66 // be called in the initialization of ExtensionManagement. |
| 62 Refresh(); | 67 Refresh(); |
| 63 providers_.push_back( | 68 providers_.push_back( |
| 64 base::MakeUnique<StandardManagementPolicyProvider>(this)); | 69 base::MakeUnique<StandardManagementPolicyProvider>(this)); |
| 65 providers_.push_back( | 70 providers_.push_back( |
| 66 base::MakeUnique<PermissionsBasedManagementPolicyProvider>(this)); | 71 base::MakeUnique<PermissionsBasedManagementPolicyProvider>(this)); |
| 67 } | 72 } |
| 68 | 73 |
| 69 ExtensionManagement::~ExtensionManagement() { | 74 ExtensionManagement::~ExtensionManagement() { |
| 70 } | 75 } |
| 71 | 76 |
| 72 void ExtensionManagement::Shutdown() { | 77 void ExtensionManagement::Shutdown() { |
| 73 pref_change_registrar_.RemoveAll(); | 78 pref_change_registrar_.RemoveAll(); |
| 74 pref_service_ = nullptr; | 79 profile_ = nullptr; |
| 75 } | 80 } |
| 76 | 81 |
| 77 void ExtensionManagement::AddObserver(Observer* observer) { | 82 void ExtensionManagement::AddObserver(Observer* observer) { |
| 78 observer_list_.AddObserver(observer); | 83 observer_list_.AddObserver(observer); |
| 79 } | 84 } |
| 80 | 85 |
| 81 void ExtensionManagement::RemoveObserver(Observer* observer) { | 86 void ExtensionManagement::RemoveObserver(Observer* observer) { |
| 82 observer_list_.RemoveObserver(observer); | 87 observer_list_.RemoveObserver(observer); |
| 83 } | 88 } |
| 84 | 89 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 103 &update_url)) { | 108 &update_url)) { |
| 104 auto iter_update_url = settings_by_update_url_.find(update_url); | 109 auto iter_update_url = settings_by_update_url_.find(update_url); |
| 105 if (iter_update_url != settings_by_update_url_.end()) | 110 if (iter_update_url != settings_by_update_url_.end()) |
| 106 return iter_update_url->second->installation_mode; | 111 return iter_update_url->second->installation_mode; |
| 107 } | 112 } |
| 108 // Fall back to default installation mode setting. | 113 // Fall back to default installation mode setting. |
| 109 return default_settings_->installation_mode; | 114 return default_settings_->installation_mode; |
| 110 } | 115 } |
| 111 | 116 |
| 112 std::unique_ptr<base::DictionaryValue> | 117 std::unique_ptr<base::DictionaryValue> |
| 118 ExtensionManagement::GetInstallListByMode( |
| 119 InstallationMode installation_mode) const { |
| 120 auto extension_dict = base::MakeUnique<base::DictionaryValue>(); |
| 121 for (const auto& entry : settings_by_id_) { |
| 122 if (entry.second->installation_mode == installation_mode) { |
| 123 ExternalPolicyLoader::AddExtension(extension_dict.get(), entry.first, |
| 124 entry.second->update_url); |
| 125 } |
| 126 } |
| 127 return extension_dict; |
| 128 } |
| 129 |
| 130 std::unique_ptr<base::DictionaryValue> |
| 113 ExtensionManagement::GetForceInstallList() const { | 131 ExtensionManagement::GetForceInstallList() const { |
| 114 std::unique_ptr<base::DictionaryValue> install_list( | 132 return GetInstallListByMode(INSTALLATION_FORCED); |
| 115 new base::DictionaryValue()); | |
| 116 for (const auto& entry : settings_by_id_) { | |
| 117 if (entry.second->installation_mode == INSTALLATION_FORCED) { | |
| 118 ExternalPolicyLoader::AddExtension(install_list.get(), entry.first, | |
| 119 entry.second->update_url); | |
| 120 } | |
| 121 } | |
| 122 return install_list; | |
| 123 } | 133 } |
| 124 | 134 |
| 125 std::unique_ptr<base::DictionaryValue> | 135 std::unique_ptr<base::DictionaryValue> |
| 126 ExtensionManagement::GetRecommendedInstallList() const { | 136 ExtensionManagement::GetRecommendedInstallList() const { |
| 127 std::unique_ptr<base::DictionaryValue> install_list( | 137 return GetInstallListByMode(INSTALLATION_RECOMMENDED); |
| 128 new base::DictionaryValue()); | |
| 129 for (const auto& entry : settings_by_id_) { | |
| 130 if (entry.second->installation_mode == INSTALLATION_RECOMMENDED) { | |
| 131 ExternalPolicyLoader::AddExtension(install_list.get(), entry.first, | |
| 132 entry.second->update_url); | |
| 133 } | |
| 134 } | |
| 135 return install_list; | |
| 136 } | 138 } |
| 137 | 139 |
| 138 bool ExtensionManagement::IsInstallationExplicitlyAllowed( | 140 bool ExtensionManagement::IsInstallationExplicitlyAllowed( |
| 139 const ExtensionId& id) const { | 141 const ExtensionId& id) const { |
| 140 auto it = settings_by_id_.find(id); | 142 auto it = settings_by_id_.find(id); |
| 141 // No settings explicitly specified for |id|. | 143 // No settings explicitly specified for |id|. |
| 142 if (it == settings_by_id_.end()) | 144 if (it == settings_by_id_.end()) |
| 143 return false; | 145 return false; |
| 144 // Checks if the extension is on the automatically installed list or | 146 // Checks if the extension is on the automatically installed list or |
| 145 // install white-list. | 147 // install white-list. |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 static_cast<const base::ListValue*>(LoadPreference( | 250 static_cast<const base::ListValue*>(LoadPreference( |
| 249 pref_names::kInstallAllowList, true, base::Value::Type::LIST)); | 251 pref_names::kInstallAllowList, true, base::Value::Type::LIST)); |
| 250 // Allow user to use preference to block certain extensions. Note that policy | 252 // Allow user to use preference to block certain extensions. Note that policy |
| 251 // managed forcelist or whitelist will always override this. | 253 // managed forcelist or whitelist will always override this. |
| 252 const base::ListValue* denied_list_pref = | 254 const base::ListValue* denied_list_pref = |
| 253 static_cast<const base::ListValue*>(LoadPreference( | 255 static_cast<const base::ListValue*>(LoadPreference( |
| 254 pref_names::kInstallDenyList, false, base::Value::Type::LIST)); | 256 pref_names::kInstallDenyList, false, base::Value::Type::LIST)); |
| 255 const base::DictionaryValue* forced_list_pref = | 257 const base::DictionaryValue* forced_list_pref = |
| 256 static_cast<const base::DictionaryValue*>(LoadPreference( | 258 static_cast<const base::DictionaryValue*>(LoadPreference( |
| 257 pref_names::kInstallForceList, true, base::Value::Type::DICTIONARY)); | 259 pref_names::kInstallForceList, true, base::Value::Type::DICTIONARY)); |
| 260 #if defined(OS_CHROMEOS) |
| 261 const base::DictionaryValue* login_screen_app_list_pref = |
| 262 static_cast<const base::DictionaryValue*>( |
| 263 LoadPreference(pref_names::kInstallLoginScreenAppList, true, |
| 264 base::Value::Type::DICTIONARY)); |
| 265 #endif |
| 258 const base::ListValue* install_sources_pref = | 266 const base::ListValue* install_sources_pref = |
| 259 static_cast<const base::ListValue*>(LoadPreference( | 267 static_cast<const base::ListValue*>(LoadPreference( |
| 260 pref_names::kAllowedInstallSites, true, base::Value::Type::LIST)); | 268 pref_names::kAllowedInstallSites, true, base::Value::Type::LIST)); |
| 261 const base::ListValue* allowed_types_pref = | 269 const base::ListValue* allowed_types_pref = |
| 262 static_cast<const base::ListValue*>(LoadPreference( | 270 static_cast<const base::ListValue*>(LoadPreference( |
| 263 pref_names::kAllowedTypes, true, base::Value::Type::LIST)); | 271 pref_names::kAllowedTypes, true, base::Value::Type::LIST)); |
| 264 const base::DictionaryValue* dict_pref = | 272 const base::DictionaryValue* dict_pref = |
| 265 static_cast<const base::DictionaryValue*>( | 273 static_cast<const base::DictionaryValue*>( |
| 266 LoadPreference(pref_names::kExtensionManagement, | 274 LoadPreference(pref_names::kExtensionManagement, |
| 267 true, | 275 true, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 } | 316 } |
| 309 | 317 |
| 310 if (denied_list_pref) { | 318 if (denied_list_pref) { |
| 311 for (base::ListValue::const_iterator it = denied_list_pref->begin(); | 319 for (base::ListValue::const_iterator it = denied_list_pref->begin(); |
| 312 it != denied_list_pref->end(); ++it) { | 320 it != denied_list_pref->end(); ++it) { |
| 313 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id)) | 321 if ((*it)->GetAsString(&id) && crx_file::id_util::IdIsValid(id)) |
| 314 AccessById(id)->installation_mode = INSTALLATION_BLOCKED; | 322 AccessById(id)->installation_mode = INSTALLATION_BLOCKED; |
| 315 } | 323 } |
| 316 } | 324 } |
| 317 | 325 |
| 318 if (forced_list_pref) { | 326 UpdateForcedExtensions(forced_list_pref); |
| 319 std::string update_url; | 327 #if defined(OS_CHROMEOS) |
| 320 for (base::DictionaryValue::Iterator it(*forced_list_pref); !it.IsAtEnd(); | 328 if (chromeos::ProfileHelper::IsSigninProfile(profile_)) |
| 321 it.Advance()) { | 329 UpdateForcedExtensions(login_screen_app_list_pref); |
| 322 if (!crx_file::id_util::IdIsValid(it.key())) | 330 #endif |
| 323 continue; | |
| 324 const base::DictionaryValue* dict_value = NULL; | |
| 325 if (it.value().GetAsDictionary(&dict_value) && | |
| 326 dict_value->GetStringWithoutPathExpansion( | |
| 327 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) { | |
| 328 internal::IndividualSettings* by_id = AccessById(it.key()); | |
| 329 by_id->installation_mode = INSTALLATION_FORCED; | |
| 330 by_id->update_url = update_url; | |
| 331 } | |
| 332 } | |
| 333 } | |
| 334 | 331 |
| 335 if (install_sources_pref) { | 332 if (install_sources_pref) { |
| 336 global_settings_->has_restricted_install_sources = true; | 333 global_settings_->has_restricted_install_sources = true; |
| 337 for (base::ListValue::const_iterator it = install_sources_pref->begin(); | 334 for (base::ListValue::const_iterator it = install_sources_pref->begin(); |
| 338 it != install_sources_pref->end(); ++it) { | 335 it != install_sources_pref->end(); ++it) { |
| 339 std::string url_pattern; | 336 std::string url_pattern; |
| 340 if ((*it)->GetAsString(&url_pattern)) { | 337 if ((*it)->GetAsString(&url_pattern)) { |
| 341 URLPattern entry(URLPattern::SCHEME_ALL); | 338 URLPattern entry(URLPattern::SCHEME_ALL); |
| 342 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { | 339 if (entry.Parse(url_pattern) == URLPattern::PARSE_SUCCESS) { |
| 343 global_settings_->install_sources.AddPattern(entry); | 340 global_settings_->install_sources.AddPattern(entry); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 } | 405 } |
| 409 } | 406 } |
| 410 } | 407 } |
| 411 } | 408 } |
| 412 } | 409 } |
| 413 | 410 |
| 414 const base::Value* ExtensionManagement::LoadPreference( | 411 const base::Value* ExtensionManagement::LoadPreference( |
| 415 const char* pref_name, | 412 const char* pref_name, |
| 416 bool force_managed, | 413 bool force_managed, |
| 417 base::Value::Type expected_type) { | 414 base::Value::Type expected_type) { |
| 418 if (!pref_service_) | 415 if (!profile_) |
| 419 return nullptr; | 416 return nullptr; |
| 420 const PrefService::Preference* pref = | 417 const PrefService::Preference* pref = |
| 421 pref_service_->FindPreference(pref_name); | 418 profile_->GetPrefs()->FindPreference(pref_name); |
| 422 if (pref && !pref->IsDefaultValue() && | 419 if (pref && !pref->IsDefaultValue() && |
| 423 (!force_managed || pref->IsManaged())) { | 420 (!force_managed || pref->IsManaged())) { |
| 424 const base::Value* value = pref->GetValue(); | 421 const base::Value* value = pref->GetValue(); |
| 425 if (value && value->IsType(expected_type)) | 422 if (value && value->IsType(expected_type)) |
| 426 return value; | 423 return value; |
| 427 } | 424 } |
| 428 return nullptr; | 425 return nullptr; |
| 429 } | 426 } |
| 430 | 427 |
| 431 void ExtensionManagement::OnExtensionPrefChanged() { | 428 void ExtensionManagement::OnExtensionPrefChanged() { |
| 432 Refresh(); | 429 Refresh(); |
| 433 NotifyExtensionManagementPrefChanged(); | 430 NotifyExtensionManagementPrefChanged(); |
| 434 } | 431 } |
| 435 | 432 |
| 436 void ExtensionManagement::NotifyExtensionManagementPrefChanged() { | 433 void ExtensionManagement::NotifyExtensionManagementPrefChanged() { |
| 437 for (auto& observer : observer_list_) | 434 for (auto& observer : observer_list_) |
| 438 observer.OnExtensionManagementSettingsChanged(); | 435 observer.OnExtensionManagementSettingsChanged(); |
| 439 } | 436 } |
| 440 | 437 |
| 438 void ExtensionManagement::UpdateForcedExtensions( |
| 439 const base::DictionaryValue* extension_dict) { |
| 440 if (!extension_dict) |
| 441 return; |
| 442 |
| 443 std::string update_url; |
| 444 for (base::DictionaryValue::Iterator it(*extension_dict); !it.IsAtEnd(); |
| 445 it.Advance()) { |
| 446 if (!crx_file::id_util::IdIsValid(it.key())) |
| 447 continue; |
| 448 const base::DictionaryValue* dict_value = nullptr; |
| 449 if (it.value().GetAsDictionary(&dict_value) && |
| 450 dict_value->GetStringWithoutPathExpansion( |
| 451 ExternalProviderImpl::kExternalUpdateUrl, &update_url)) { |
| 452 internal::IndividualSettings* by_id = AccessById(it.key()); |
| 453 by_id->installation_mode = INSTALLATION_FORCED; |
| 454 by_id->update_url = update_url; |
| 455 } |
| 456 } |
| 457 } |
| 458 |
| 441 internal::IndividualSettings* ExtensionManagement::AccessById( | 459 internal::IndividualSettings* ExtensionManagement::AccessById( |
| 442 const ExtensionId& id) { | 460 const ExtensionId& id) { |
| 443 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id; | 461 DCHECK(crx_file::id_util::IdIsValid(id)) << "Invalid ID: " << id; |
| 444 std::unique_ptr<internal::IndividualSettings>& settings = settings_by_id_[id]; | 462 std::unique_ptr<internal::IndividualSettings>& settings = settings_by_id_[id]; |
| 445 if (!settings) { | 463 if (!settings) { |
| 446 settings = | 464 settings = |
| 447 base::MakeUnique<internal::IndividualSettings>(default_settings_.get()); | 465 base::MakeUnique<internal::IndividualSettings>(default_settings_.get()); |
| 448 } | 466 } |
| 449 return settings.get(); | 467 return settings.get(); |
| 450 } | 468 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 477 BrowserContextDependencyManager::GetInstance()) { | 495 BrowserContextDependencyManager::GetInstance()) { |
| 478 } | 496 } |
| 479 | 497 |
| 480 ExtensionManagementFactory::~ExtensionManagementFactory() { | 498 ExtensionManagementFactory::~ExtensionManagementFactory() { |
| 481 } | 499 } |
| 482 | 500 |
| 483 KeyedService* ExtensionManagementFactory::BuildServiceInstanceFor( | 501 KeyedService* ExtensionManagementFactory::BuildServiceInstanceFor( |
| 484 content::BrowserContext* context) const { | 502 content::BrowserContext* context) const { |
| 485 TRACE_EVENT0("browser,startup", | 503 TRACE_EVENT0("browser,startup", |
| 486 "ExtensionManagementFactory::BuildServiceInstanceFor"); | 504 "ExtensionManagementFactory::BuildServiceInstanceFor"); |
| 487 return new ExtensionManagement( | 505 return new ExtensionManagement(Profile::FromBrowserContext(context)); |
| 488 Profile::FromBrowserContext(context)->GetPrefs()); | |
| 489 } | 506 } |
| 490 | 507 |
| 491 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( | 508 content::BrowserContext* ExtensionManagementFactory::GetBrowserContextToUse( |
| 492 content::BrowserContext* context) const { | 509 content::BrowserContext* context) const { |
| 493 return chrome::GetBrowserContextRedirectedInIncognito(context); | 510 return chrome::GetBrowserContextRedirectedInIncognito(context); |
| 494 } | 511 } |
| 495 | 512 |
| 496 void ExtensionManagementFactory::RegisterProfilePrefs( | 513 void ExtensionManagementFactory::RegisterProfilePrefs( |
| 497 user_prefs::PrefRegistrySyncable* user_prefs) { | 514 user_prefs::PrefRegistrySyncable* user_prefs) { |
| 498 user_prefs->RegisterDictionaryPref(pref_names::kExtensionManagement); | 515 user_prefs->RegisterDictionaryPref(pref_names::kExtensionManagement); |
| 499 } | 516 } |
| 500 | 517 |
| 501 } // namespace extensions | 518 } // namespace extensions |
| OLD | NEW |