| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 | 222 |
| 223 class ExtensionServiceBackend | 223 class ExtensionServiceBackend |
| 224 : public base::RefCountedThreadSafe<ExtensionServiceBackend> { | 224 : public base::RefCountedThreadSafe<ExtensionServiceBackend> { |
| 225 public: | 225 public: |
| 226 // |install_directory| is a path where to look for extensions to load. | 226 // |install_directory| is a path where to look for extensions to load. |
| 227 ExtensionServiceBackend( | 227 ExtensionServiceBackend( |
| 228 base::WeakPtr<ExtensionService> frontend, | 228 base::WeakPtr<ExtensionService> frontend, |
| 229 const FilePath& install_directory); | 229 const FilePath& install_directory); |
| 230 | 230 |
| 231 // Loads a single extension from |path| where |path| is the top directory of | 231 // Loads a single extension from |path| where |path| is the top directory of |
| 232 // a specific extension where its manifest file lives. | 232 // a specific extension where its manifest file lives. If |prompt_for_plugins| |
| 233 // is true and the extension contains plugins, we prompt the user before |
| 234 // loading. |
| 233 // Errors are reported through ExtensionErrorReporter. On success, | 235 // Errors are reported through ExtensionErrorReporter. On success, |
| 234 // AddExtension() is called. | 236 // AddExtension() is called. |
| 235 // TODO(erikkay): It might be useful to be able to load a packed extension | 237 // TODO(erikkay): It might be useful to be able to load a packed extension |
| 236 // (presumably into memory) without installing it. | 238 // (presumably into memory) without installing it. |
| 237 void LoadSingleExtension(const FilePath &path); | 239 void LoadSingleExtension(const FilePath &path, bool prompt_for_plugins); |
| 238 | 240 |
| 239 private: | 241 private: |
| 240 friend class base::RefCountedThreadSafe<ExtensionServiceBackend>; | 242 friend class base::RefCountedThreadSafe<ExtensionServiceBackend>; |
| 241 | 243 |
| 242 virtual ~ExtensionServiceBackend(); | 244 virtual ~ExtensionServiceBackend(); |
| 243 | 245 |
| 244 // LoadSingleExtension needs to check the file access preference, which needs | 246 // LoadSingleExtension needs to check the file access preference, which needs |
| 245 // to happen back on the UI thread, so it posts CheckExtensionFileAccess on | 247 // to happen back on the UI thread, so it posts CheckExtensionFileAccess on |
| 246 // the UI thread. In turn, once that gets the pref, it goes back to the | 248 // the UI thread. In turn, once that gets the pref, it goes back to the |
| 247 // file thread with LoadSingleExtensionWithFileAccess. | 249 // file thread with LoadSingleExtensionWithFileAccess. |
| 248 void CheckExtensionFileAccess(const FilePath& extension_path); | 250 void CheckExtensionFileAccess(const FilePath& extension_path, |
| 251 bool prompt_for_plugins); |
| 249 void LoadSingleExtensionWithFileAccess( | 252 void LoadSingleExtensionWithFileAccess( |
| 250 const FilePath &path, bool allow_file_access); | 253 const FilePath &path, bool allow_file_access, bool prompt_for_plugins); |
| 251 | 254 |
| 252 // Notify the frontend that there was an error loading an extension. | 255 // Notify the frontend that there was an error loading an extension. |
| 253 void ReportExtensionLoadError(const FilePath& extension_path, | 256 void ReportExtensionLoadError(const FilePath& extension_path, |
| 254 const std::string& error); | 257 const std::string& error); |
| 255 | 258 |
| 256 // Notify the frontend that an extension was installed. | 259 // Notify the frontend that an extension was installed. |
| 257 void OnLoadSingleExtension(const scoped_refptr<const Extension>& extension); | 260 void OnLoadSingleExtension(const scoped_refptr<const Extension>& extension, |
| 261 bool prompt_for_plugins); |
| 258 | 262 |
| 259 base::WeakPtr<ExtensionService> frontend_; | 263 base::WeakPtr<ExtensionService> frontend_; |
| 260 | 264 |
| 261 // The top-level extensions directory being installed to. | 265 // The top-level extensions directory being installed to. |
| 262 FilePath install_directory_; | 266 FilePath install_directory_; |
| 263 | 267 |
| 264 DISALLOW_COPY_AND_ASSIGN(ExtensionServiceBackend); | 268 DISALLOW_COPY_AND_ASSIGN(ExtensionServiceBackend); |
| 265 }; | 269 }; |
| 266 | 270 |
| 267 ExtensionServiceBackend::ExtensionServiceBackend( | 271 ExtensionServiceBackend::ExtensionServiceBackend( |
| 268 base::WeakPtr<ExtensionService> frontend, | 272 base::WeakPtr<ExtensionService> frontend, |
| 269 const FilePath& install_directory) | 273 const FilePath& install_directory) |
| 270 : frontend_(frontend), | 274 : frontend_(frontend), |
| 271 install_directory_(install_directory) { | 275 install_directory_(install_directory) { |
| 272 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 276 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 273 } | 277 } |
| 274 | 278 |
| 275 ExtensionServiceBackend::~ExtensionServiceBackend() { | 279 ExtensionServiceBackend::~ExtensionServiceBackend() { |
| 276 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 280 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 277 BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 281 BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 278 } | 282 } |
| 279 | 283 |
| 280 void ExtensionServiceBackend::LoadSingleExtension(const FilePath& path_in) { | 284 void ExtensionServiceBackend::LoadSingleExtension(const FilePath& path_in, |
| 285 bool prompt_for_plugins) { |
| 281 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 286 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 282 | 287 |
| 283 FilePath extension_path = path_in; | 288 FilePath extension_path = path_in; |
| 284 file_util::AbsolutePath(&extension_path); | 289 file_util::AbsolutePath(&extension_path); |
| 285 | 290 |
| 286 if (!BrowserThread::PostTask( | 291 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 287 BrowserThread::UI, FROM_HERE, | 292 NewRunnableMethod(this, |
| 288 NewRunnableMethod( | 293 &ExtensionServiceBackend::CheckExtensionFileAccess, |
| 289 this, | 294 extension_path, prompt_for_plugins)); |
| 290 &ExtensionServiceBackend::CheckExtensionFileAccess, | |
| 291 extension_path))) | |
| 292 NOTREACHED(); | |
| 293 } | 295 } |
| 294 | 296 |
| 295 void ExtensionServiceBackend::CheckExtensionFileAccess( | 297 void ExtensionServiceBackend::CheckExtensionFileAccess( |
| 296 const FilePath& extension_path) { | 298 const FilePath& extension_path, bool prompt_for_plugins) { |
| 297 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 299 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 298 std::string id = Extension::GenerateIdForPath(extension_path); | 300 std::string id = Extension::GenerateIdForPath(extension_path); |
| 299 // Unpacked extensions default to allowing file access, but if that has been | 301 // Unpacked extensions default to allowing file access, but if that has been |
| 300 // overridden, don't reset the value. | 302 // overridden, don't reset the value. |
| 301 bool allow_file_access = | 303 bool allow_file_access = |
| 302 Extension::ShouldAlwaysAllowFileAccess(Extension::LOAD) && | 304 Extension::ShouldAlwaysAllowFileAccess(Extension::LOAD) && |
| 303 !frontend_->extension_prefs()->HasAllowFileAccessSetting(id); | 305 !frontend_->extension_prefs()->HasAllowFileAccessSetting(id); |
| 304 | 306 |
| 305 if (!BrowserThread::PostTask( | 307 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 306 BrowserThread::FILE, FROM_HERE, | 308 NewRunnableMethod( |
| 307 NewRunnableMethod( | 309 this, |
| 308 this, | 310 &ExtensionServiceBackend::LoadSingleExtensionWithFileAccess, |
| 309 &ExtensionServiceBackend::LoadSingleExtensionWithFileAccess, | 311 extension_path, allow_file_access, prompt_for_plugins)); |
| 310 extension_path, | |
| 311 allow_file_access))) | |
| 312 NOTREACHED(); | |
| 313 } | 312 } |
| 314 | 313 |
| 315 | |
| 316 void ExtensionServiceBackend::LoadSingleExtensionWithFileAccess( | 314 void ExtensionServiceBackend::LoadSingleExtensionWithFileAccess( |
| 317 const FilePath& extension_path, bool allow_file_access) { | 315 const FilePath& extension_path, |
| 316 bool allow_file_access, |
| 317 bool prompt_for_plugins) { |
| 318 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 318 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 319 int flags = allow_file_access ? | 319 int flags = allow_file_access ? |
| 320 Extension::ALLOW_FILE_ACCESS : Extension::NO_FLAGS; | 320 Extension::ALLOW_FILE_ACCESS : Extension::NO_FLAGS; |
| 321 if (Extension::ShouldDoStrictErrorChecking(Extension::LOAD)) | 321 if (Extension::ShouldDoStrictErrorChecking(Extension::LOAD)) |
| 322 flags |= Extension::STRICT_ERROR_CHECKS; | 322 flags |= Extension::STRICT_ERROR_CHECKS; |
| 323 std::string error; | 323 std::string error; |
| 324 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( | 324 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( |
| 325 extension_path, | 325 extension_path, |
| 326 Extension::LOAD, | 326 Extension::LOAD, |
| 327 flags, | 327 flags, |
| 328 &error)); | 328 &error)); |
| 329 | 329 |
| 330 if (!extension) { | 330 if (!extension) { |
| 331 if (!BrowserThread::PostTask( | 331 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 332 BrowserThread::UI, FROM_HERE, | 332 NewRunnableMethod( |
| 333 NewRunnableMethod( | 333 this, |
| 334 this, | 334 &ExtensionServiceBackend::ReportExtensionLoadError, |
| 335 &ExtensionServiceBackend::ReportExtensionLoadError, | 335 extension_path, error)); |
| 336 extension_path, error))) | |
| 337 NOTREACHED() << error; | |
| 338 return; | 336 return; |
| 339 } | 337 } |
| 340 | 338 |
| 341 // Report this as an installed extension so that it gets remembered in the | 339 // Report this as an installed extension so that it gets remembered in the |
| 342 // prefs. | 340 // prefs. |
| 343 if (!BrowserThread::PostTask( | 341 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 344 BrowserThread::UI, FROM_HERE, | 342 NewRunnableMethod( |
| 345 NewRunnableMethod( | 343 this, |
| 346 this, | 344 &ExtensionServiceBackend::OnLoadSingleExtension, |
| 347 &ExtensionServiceBackend::OnLoadSingleExtension, | 345 extension, prompt_for_plugins)); |
| 348 extension))) | |
| 349 NOTREACHED(); | |
| 350 } | 346 } |
| 351 | 347 |
| 352 void ExtensionServiceBackend::ReportExtensionLoadError( | 348 void ExtensionServiceBackend::ReportExtensionLoadError( |
| 353 const FilePath& extension_path, const std::string &error) { | 349 const FilePath& extension_path, const std::string &error) { |
| 354 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 350 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 355 if (frontend_.get()) | 351 if (frontend_.get()) |
| 356 frontend_->ReportExtensionLoadError( | 352 frontend_->ReportExtensionLoadError( |
| 357 extension_path, error, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, | 353 extension_path, error, chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, |
| 358 true /* alert_on_error */); | 354 true /* alert_on_error */); |
| 359 } | 355 } |
| 360 | 356 |
| 361 void ExtensionServiceBackend::OnLoadSingleExtension( | 357 void ExtensionServiceBackend::OnLoadSingleExtension( |
| 362 const scoped_refptr<const Extension>& extension) { | 358 const scoped_refptr<const Extension>& extension, bool prompt_for_plugins) { |
| 363 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 359 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 364 if (frontend_.get()) | 360 if (frontend_.get()) |
| 365 frontend_->OnLoadSingleExtension(extension); | 361 frontend_->OnLoadSingleExtension(extension, prompt_for_plugins); |
| 366 } | 362 } |
| 367 | 363 |
| 368 void ExtensionService::CheckExternalUninstall(const std::string& id) { | 364 void ExtensionService::CheckExternalUninstall(const std::string& id) { |
| 369 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 365 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 370 | 366 |
| 371 // Check if the providers know about this extension. | 367 // Check if the providers know about this extension. |
| 372 ProviderCollection::const_iterator i; | 368 ProviderCollection::const_iterator i; |
| 373 for (i = external_extension_providers_.begin(); | 369 for (i = external_extension_providers_.begin(); |
| 374 i != external_extension_providers_.end(); ++i) { | 370 i != external_extension_providers_.end(); ++i) { |
| 375 DCHECK(i->get()->IsReady()); | 371 DCHECK(i->get()->IsReady()); |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 const Extension* extension) { | 988 const Extension* extension) { |
| 993 CHECK(extension); | 989 CHECK(extension); |
| 994 RecordPermissionMessagesHistogram( | 990 RecordPermissionMessagesHistogram( |
| 995 extension, "Extensions.Permissions_ReEnable"); | 991 extension, "Extensions.Permissions_ReEnable"); |
| 996 GrantPermissions(extension); | 992 GrantPermissions(extension); |
| 997 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); | 993 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); |
| 998 EnableExtension(extension->id()); | 994 EnableExtension(extension->id()); |
| 999 } | 995 } |
| 1000 | 996 |
| 1001 void ExtensionService::LoadExtension(const FilePath& extension_path) { | 997 void ExtensionService::LoadExtension(const FilePath& extension_path) { |
| 1002 if (!BrowserThread::PostTask( | 998 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 1003 BrowserThread::FILE, FROM_HERE, | 999 NewRunnableMethod(backend_.get(), |
| 1004 NewRunnableMethod( | 1000 &ExtensionServiceBackend::LoadSingleExtension, |
| 1005 backend_.get(), | 1001 extension_path, true)); |
| 1006 &ExtensionServiceBackend::LoadSingleExtension, | 1002 } |
| 1007 extension_path))) | 1003 |
| 1008 NOTREACHED(); | 1004 void ExtensionService::LoadExtensionFromCommandLine( |
| 1005 const FilePath& extension_path) { |
| 1006 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 1007 NewRunnableMethod(backend_.get(), |
| 1008 &ExtensionServiceBackend::LoadSingleExtension, |
| 1009 extension_path, false)); |
| 1009 } | 1010 } |
| 1010 | 1011 |
| 1011 void ExtensionService::LoadComponentExtensions() { | 1012 void ExtensionService::LoadComponentExtensions() { |
| 1012 for (RegisteredComponentExtensions::iterator it = | 1013 for (RegisteredComponentExtensions::iterator it = |
| 1013 component_extension_manifests_.begin(); | 1014 component_extension_manifests_.begin(); |
| 1014 it != component_extension_manifests_.end(); ++it) { | 1015 it != component_extension_manifests_.end(); ++it) { |
| 1015 LoadComponentExtension(*it); | 1016 LoadComponentExtension(*it); |
| 1016 } | 1017 } |
| 1017 } | 1018 } |
| 1018 | 1019 |
| (...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2007 std::set<std::string> extension_ids; | 2008 std::set<std::string> extension_ids; |
| 2008 for (size_t i = 0; i < extensions_.size(); ++i) { | 2009 for (size_t i = 0; i < extensions_.size(); ++i) { |
| 2009 if (!extensions_[i]->is_theme() && | 2010 if (!extensions_[i]->is_theme() && |
| 2010 extensions_[i]->location() != Extension::COMPONENT) | 2011 extensions_[i]->location() != Extension::COMPONENT) |
| 2011 extension_ids.insert(extensions_[i]->id()); | 2012 extension_ids.insert(extensions_[i]->id()); |
| 2012 } | 2013 } |
| 2013 | 2014 |
| 2014 child_process_logging::SetActiveExtensions(extension_ids); | 2015 child_process_logging::SetActiveExtensions(extension_ids); |
| 2015 } | 2016 } |
| 2016 | 2017 |
| 2017 void ExtensionService::OnLoadSingleExtension(const Extension* extension) { | 2018 void ExtensionService::OnLoadSingleExtension(const Extension* extension, |
| 2019 bool prompt_for_plugins) { |
| 2018 // If this is a new install of an extension with plugins, prompt the user | 2020 // If this is a new install of an extension with plugins, prompt the user |
| 2019 // first. | 2021 // first. |
| 2020 if (show_extensions_prompts_ && | 2022 if (show_extensions_prompts_ && prompt_for_plugins && |
| 2021 !extension->plugins().empty() && | 2023 !extension->plugins().empty() && |
| 2022 disabled_extension_paths_.find(extension->id()) == | 2024 disabled_extension_paths_.find(extension->id()) == |
| 2023 disabled_extension_paths_.end()) { | 2025 disabled_extension_paths_.end()) { |
| 2024 SimpleExtensionLoadPrompt* prompt = new SimpleExtensionLoadPrompt( | 2026 SimpleExtensionLoadPrompt* prompt = new SimpleExtensionLoadPrompt( |
| 2025 profile_, weak_ptr_factory_.GetWeakPtr(), extension); | 2027 profile_, weak_ptr_factory_.GetWeakPtr(), extension); |
| 2026 prompt->ShowPrompt(); | 2028 prompt->ShowPrompt(); |
| 2027 return; // continues in SimpleExtensionLoadPrompt::InstallUI* | 2029 return; // continues in SimpleExtensionLoadPrompt::InstallUI* |
| 2028 } | 2030 } |
| 2029 OnExtensionInstalled(extension, false); // Not from web store. | 2031 OnExtensionInstalled(extension, false); // Not from web store. |
| 2030 } | 2032 } |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2443 | 2445 |
| 2444 ExtensionService::NaClModuleInfoList::iterator | 2446 ExtensionService::NaClModuleInfoList::iterator |
| 2445 ExtensionService::FindNaClModule(const GURL& url) { | 2447 ExtensionService::FindNaClModule(const GURL& url) { |
| 2446 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); | 2448 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); |
| 2447 iter != nacl_module_list_.end(); ++iter) { | 2449 iter != nacl_module_list_.end(); ++iter) { |
| 2448 if (iter->url == url) | 2450 if (iter->url == url) |
| 2449 return iter; | 2451 return iter; |
| 2450 } | 2452 } |
| 2451 return nacl_module_list_.end(); | 2453 return nacl_module_list_.end(); |
| 2452 } | 2454 } |
| OLD | NEW |