Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/external_provider_impl.h" | 5 #include "chrome/browser/extensions/external_provider_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 | 112 |
| 113 void ExternalProviderImpl::SetPrefs(base::DictionaryValue* prefs) { | 113 void ExternalProviderImpl::SetPrefs(base::DictionaryValue* prefs) { |
| 114 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 114 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 115 | 115 |
| 116 // Check if the service is still alive. It is possible that it went | 116 // Check if the service is still alive. It is possible that it went |
| 117 // away while |loader_| was working on the FILE thread. | 117 // away while |loader_| was working on the FILE thread. |
| 118 if (!service_) return; | 118 if (!service_) return; |
| 119 | 119 |
| 120 prefs_.reset(prefs); | 120 prefs_.reset(prefs); |
| 121 ready_ = true; // Queries for extensions are allowed from this point. | 121 ready_ = true; // Queries for extensions are allowed from this point. |
| 122 NotifyExtensionsFromPrefs(true); | |
| 123 service_->OnExternalProviderReady(this); | |
| 124 } | |
| 122 | 125 |
| 126 void ExternalProviderImpl::UpdatePrefs(base::DictionaryValue* prefs) { | |
|
Devlin
2016/01/21 00:14:26
This is a little hard to review - can you un-move
lazyboy
2016/01/21 21:02:12
Done.
| |
| 127 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 128 // We only expect updates from windows registry. | |
| 129 CHECK(crx_location_ == Manifest::EXTERNAL_REGISTRY); | |
| 130 | |
| 131 // Check if the service is still alive. It is possible that it went | |
| 132 // away while |loader_| was working on the FILE thread. | |
| 133 if (!service_) | |
| 134 return; | |
| 135 | |
| 136 std::set<std::string> removed_extensions; | |
| 137 // Find extensions that were removed by this ExternalProvider. | |
| 138 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) { | |
| 139 const std::string& extension_id = i.key(); | |
| 140 // Don't bother about invalid ids. | |
| 141 if (!crx_file::id_util::IdIsValid(extension_id)) | |
| 142 continue; | |
| 143 if (!prefs->HasKey(extension_id)) | |
| 144 removed_extensions.insert(extension_id); | |
| 145 } | |
| 146 | |
| 147 prefs_.reset(prefs); | |
| 148 | |
| 149 // Notify ExtensionService about all the extension this provider has found | |
| 150 // "updates" for. | |
| 151 // For each update found, this will end up calling | |
| 152 // OnExternalExtensionUpdateUrlFound() or OnExternalExtensionFileFound(). | |
| 153 NotifyExtensionsFromPrefs(false); | |
| 154 // Then notify about the completion of update, with list of extensions that | |
| 155 // were removed. | |
| 156 service_->OnExternalProviderUpdateComplete(this, removed_extensions); | |
| 157 } | |
| 158 | |
| 159 void ExternalProviderImpl::ServiceShutdown() { | |
| 160 service_ = NULL; | |
| 161 } | |
| 162 | |
| 163 bool ExternalProviderImpl::IsReady() const { | |
| 164 return ready_; | |
| 165 } | |
| 166 | |
| 167 bool ExternalProviderImpl::HasExtension( | |
| 168 const std::string& id) const { | |
| 169 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 170 CHECK(prefs_.get()); | |
| 171 CHECK(ready_); | |
| 172 return prefs_->HasKey(id); | |
| 173 } | |
| 174 | |
| 175 bool ExternalProviderImpl::GetExtensionDetails( | |
| 176 const std::string& id, Manifest::Location* location, | |
| 177 scoped_ptr<Version>* version) const { | |
| 178 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 179 CHECK(prefs_.get()); | |
| 180 CHECK(ready_); | |
| 181 base::DictionaryValue* extension = NULL; | |
| 182 if (!prefs_->GetDictionary(id, &extension)) | |
| 183 return false; | |
| 184 | |
| 185 Manifest::Location loc = Manifest::INVALID_LOCATION; | |
| 186 if (extension->HasKey(kExternalUpdateUrl)) { | |
| 187 loc = download_location_; | |
| 188 | |
| 189 } else if (extension->HasKey(kExternalCrx)) { | |
| 190 loc = crx_location_; | |
| 191 | |
| 192 std::string external_version; | |
| 193 if (!extension->GetString(kExternalVersion, &external_version)) | |
| 194 return false; | |
| 195 | |
| 196 if (version) | |
| 197 version->reset(new Version(external_version)); | |
| 198 | |
| 199 } else { | |
| 200 NOTREACHED(); // Chrome should not allow prefs to get into this state. | |
| 201 return false; | |
| 202 } | |
| 203 | |
| 204 if (location) | |
| 205 *location = loc; | |
| 206 | |
| 207 return true; | |
| 208 } | |
| 209 | |
| 210 bool ExternalProviderImpl::HandleMinProfileVersion( | |
| 211 const base::DictionaryValue* extension, | |
| 212 const std::string& extension_id, | |
| 213 std::set<std::string>* unsupported_extensions) { | |
| 214 std::string min_profile_created_by_version; | |
| 215 if (profile_ && | |
| 216 extension->GetString(kMinProfileCreatedByVersion, | |
| 217 &min_profile_created_by_version)) { | |
| 218 Version profile_version( | |
| 219 profile_->GetPrefs()->GetString(prefs::kProfileCreatedByVersion)); | |
| 220 Version min_version(min_profile_created_by_version); | |
| 221 if (min_version.IsValid() && profile_version.CompareTo(min_version) < 0) { | |
| 222 unsupported_extensions->insert(extension_id); | |
| 223 VLOG(1) << "Skip installing (or uninstall) external extension: " | |
| 224 << extension_id | |
| 225 << " profile.created_by_version: " << profile_version.GetString() | |
| 226 << " min_profile_created_by_version: " | |
| 227 << min_profile_created_by_version; | |
| 228 return false; | |
| 229 } | |
| 230 } | |
| 231 return true; | |
| 232 } | |
| 233 | |
| 234 bool ExternalProviderImpl::HandleDoNotInstallForEnterprise( | |
| 235 const base::DictionaryValue* extension, | |
| 236 const std::string& extension_id, | |
| 237 std::set<std::string>* unsupported_extensions) { | |
| 238 bool do_not_install_for_enterprise = false; | |
| 239 if (extension->GetBoolean(kDoNotInstallForEnterprise, | |
| 240 &do_not_install_for_enterprise) && | |
| 241 do_not_install_for_enterprise) { | |
| 242 const policy::ProfilePolicyConnector* const connector = | |
| 243 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile_); | |
| 244 if (connector->IsManaged()) { | |
| 245 unsupported_extensions->insert(extension_id); | |
| 246 VLOG(1) << "Skip installing (or uninstall) external extension " | |
| 247 << extension_id << " restricted for managed user"; | |
| 248 return false; | |
| 249 } | |
| 250 } | |
| 251 return true; | |
| 252 } | |
| 253 | |
| 254 void ExternalProviderImpl::NotifyExtensionsFromPrefs(bool is_initial_load) { | |
| 123 // Set of unsupported extensions that need to be deleted from prefs_. | 255 // Set of unsupported extensions that need to be deleted from prefs_. |
| 124 std::set<std::string> unsupported_extensions; | 256 std::set<std::string> unsupported_extensions; |
| 125 | 257 |
| 126 // Notify ExtensionService about all the extensions this provider has. | 258 // Notify ExtensionService about all the extensions this provider has. |
| 127 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) { | 259 for (base::DictionaryValue::Iterator i(*prefs_); !i.IsAtEnd(); i.Advance()) { |
| 128 const std::string& extension_id = i.key(); | 260 const std::string& extension_id = i.key(); |
| 129 const base::DictionaryValue* extension = NULL; | 261 const base::DictionaryValue* extension = NULL; |
| 130 | 262 |
| 131 if (!crx_file::id_util::IdIsValid(extension_id)) { | 263 if (!crx_file::id_util::IdIsValid(extension_id)) { |
| 132 LOG(WARNING) << "Malformed extension dictionary: key " | 264 LOG(WARNING) << "Malformed extension dictionary: key " |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 313 << extension_id.c_str() << ". Key " << kExternalUpdateUrl | 445 << extension_id.c_str() << ". Key " << kExternalUpdateUrl |
| 314 << " has value \"" << external_update_url | 446 << " has value \"" << external_update_url |
| 315 << "\", which is not a valid URL."; | 447 << "\", which is not a valid URL."; |
| 316 continue; | 448 continue; |
| 317 } | 449 } |
| 318 service_->OnExternalExtensionUpdateUrlFound(extension_id, | 450 service_->OnExternalExtensionUpdateUrlFound(extension_id, |
| 319 install_parameter, | 451 install_parameter, |
| 320 update_url, | 452 update_url, |
| 321 download_location_, | 453 download_location_, |
| 322 creation_flags, | 454 creation_flags, |
| 323 auto_acknowledge_); | 455 auto_acknowledge_, |
| 456 is_initial_load); | |
| 324 } | 457 } |
| 325 } | 458 } |
| 326 | 459 |
| 327 for (std::set<std::string>::iterator it = unsupported_extensions.begin(); | 460 for (std::set<std::string>::iterator it = unsupported_extensions.begin(); |
| 328 it != unsupported_extensions.end(); ++it) { | 461 it != unsupported_extensions.end(); ++it) { |
| 329 // Remove extension for the list of know external extensions. The extension | 462 // Remove extension for the list of know external extensions. The extension |
| 330 // will be uninstalled later because provider doesn't provide it anymore. | 463 // will be uninstalled later because provider doesn't provide it anymore. |
| 331 prefs_->Remove(*it, NULL); | 464 prefs_->Remove(*it, NULL); |
| 332 } | 465 } |
| 333 | |
| 334 service_->OnExternalProviderReady(this); | |
| 335 } | |
| 336 | |
| 337 void ExternalProviderImpl::ServiceShutdown() { | |
| 338 service_ = NULL; | |
| 339 } | |
| 340 | |
| 341 bool ExternalProviderImpl::IsReady() const { | |
| 342 return ready_; | |
| 343 } | |
| 344 | |
| 345 bool ExternalProviderImpl::HasExtension( | |
| 346 const std::string& id) const { | |
| 347 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 348 CHECK(prefs_.get()); | |
| 349 CHECK(ready_); | |
| 350 return prefs_->HasKey(id); | |
| 351 } | |
| 352 | |
| 353 bool ExternalProviderImpl::GetExtensionDetails( | |
| 354 const std::string& id, Manifest::Location* location, | |
| 355 scoped_ptr<Version>* version) const { | |
| 356 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 357 CHECK(prefs_.get()); | |
| 358 CHECK(ready_); | |
| 359 base::DictionaryValue* extension = NULL; | |
| 360 if (!prefs_->GetDictionary(id, &extension)) | |
| 361 return false; | |
| 362 | |
| 363 Manifest::Location loc = Manifest::INVALID_LOCATION; | |
| 364 if (extension->HasKey(kExternalUpdateUrl)) { | |
| 365 loc = download_location_; | |
| 366 | |
| 367 } else if (extension->HasKey(kExternalCrx)) { | |
| 368 loc = crx_location_; | |
| 369 | |
| 370 std::string external_version; | |
| 371 if (!extension->GetString(kExternalVersion, &external_version)) | |
| 372 return false; | |
| 373 | |
| 374 if (version) | |
| 375 version->reset(new Version(external_version)); | |
| 376 | |
| 377 } else { | |
| 378 NOTREACHED(); // Chrome should not allow prefs to get into this state. | |
| 379 return false; | |
| 380 } | |
| 381 | |
| 382 if (location) | |
| 383 *location = loc; | |
| 384 | |
| 385 return true; | |
| 386 } | |
| 387 | |
| 388 bool ExternalProviderImpl::HandleMinProfileVersion( | |
| 389 const base::DictionaryValue* extension, | |
| 390 const std::string& extension_id, | |
| 391 std::set<std::string>* unsupported_extensions) { | |
| 392 std::string min_profile_created_by_version; | |
| 393 if (profile_ && | |
| 394 extension->GetString(kMinProfileCreatedByVersion, | |
| 395 &min_profile_created_by_version)) { | |
| 396 Version profile_version( | |
| 397 profile_->GetPrefs()->GetString(prefs::kProfileCreatedByVersion)); | |
| 398 Version min_version(min_profile_created_by_version); | |
| 399 if (min_version.IsValid() && profile_version.CompareTo(min_version) < 0) { | |
| 400 unsupported_extensions->insert(extension_id); | |
| 401 VLOG(1) << "Skip installing (or uninstall) external extension: " | |
| 402 << extension_id | |
| 403 << " profile.created_by_version: " << profile_version.GetString() | |
| 404 << " min_profile_created_by_version: " | |
| 405 << min_profile_created_by_version; | |
| 406 return false; | |
| 407 } | |
| 408 } | |
| 409 return true; | |
| 410 } | |
| 411 | |
| 412 bool ExternalProviderImpl::HandleDoNotInstallForEnterprise( | |
| 413 const base::DictionaryValue* extension, | |
| 414 const std::string& extension_id, | |
| 415 std::set<std::string>* unsupported_extensions) { | |
| 416 bool do_not_install_for_enterprise = false; | |
| 417 if (extension->GetBoolean(kDoNotInstallForEnterprise, | |
| 418 &do_not_install_for_enterprise) && | |
| 419 do_not_install_for_enterprise) { | |
| 420 const policy::ProfilePolicyConnector* const connector = | |
| 421 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile_); | |
| 422 if (connector->IsManaged()) { | |
| 423 unsupported_extensions->insert(extension_id); | |
| 424 VLOG(1) << "Skip installing (or uninstall) external extension " | |
| 425 << extension_id << " restricted for managed user"; | |
| 426 return false; | |
| 427 } | |
| 428 } | |
| 429 return true; | |
| 430 } | 466 } |
| 431 | 467 |
| 432 // static | 468 // static |
| 433 void ExternalProviderImpl::CreateExternalProviders( | 469 void ExternalProviderImpl::CreateExternalProviders( |
| 434 VisitorInterface* service, | 470 VisitorInterface* service, |
| 435 Profile* profile, | 471 Profile* profile, |
| 436 ProviderCollection* provider_list) { | 472 ProviderCollection* provider_list) { |
| 437 TRACE_EVENT0("browser,startup", | 473 TRACE_EVENT0("browser,startup", |
| 438 "ExternalProviderImpl::CreateExternalProviders"); | 474 "ExternalProviderImpl::CreateExternalProviders"); |
| 439 scoped_refptr<ExternalLoader> external_loader; | 475 scoped_refptr<ExternalLoader> external_loader; |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 new ExternalProviderImpl( | 727 new ExternalProviderImpl( |
| 692 service, | 728 service, |
| 693 new ExternalComponentLoader(profile), | 729 new ExternalComponentLoader(profile), |
| 694 profile, | 730 profile, |
| 695 Manifest::INVALID_LOCATION, | 731 Manifest::INVALID_LOCATION, |
| 696 Manifest::EXTERNAL_COMPONENT, | 732 Manifest::EXTERNAL_COMPONENT, |
| 697 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT))); | 733 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT))); |
| 698 } | 734 } |
| 699 | 735 |
| 700 } // namespace extensions | 736 } // namespace extensions |
| OLD | NEW |