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 |