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 |