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/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 #include "chrome/common/extensions/manifest.h" | 100 #include "chrome/common/extensions/manifest.h" |
| 101 #include "chrome/common/pref_names.h" | 101 #include "chrome/common/pref_names.h" |
| 102 #include "chrome/common/url_constants.h" | 102 #include "chrome/common/url_constants.h" |
| 103 #include "content/public/browser/browser_thread.h" | 103 #include "content/public/browser/browser_thread.h" |
| 104 #include "content/public/browser/devtools_agent_host_registry.h" | 104 #include "content/public/browser/devtools_agent_host_registry.h" |
| 105 #include "content/public/browser/devtools_manager.h" | 105 #include "content/public/browser/devtools_manager.h" |
| 106 #include "content/public/browser/notification_service.h" | 106 #include "content/public/browser/notification_service.h" |
| 107 #include "content/public/browser/notification_types.h" | 107 #include "content/public/browser/notification_types.h" |
| 108 #include "content/public/browser/plugin_service.h" | 108 #include "content/public/browser/plugin_service.h" |
| 109 #include "content/public/browser/render_process_host.h" | 109 #include "content/public/browser/render_process_host.h" |
| 110 #include "content/public/browser/site_instance.h" | |
| 111 #include "content/public/browser/storage_partition.h" | |
| 110 #include "content/public/common/pepper_plugin_info.h" | 112 #include "content/public/common/pepper_plugin_info.h" |
| 111 #include "extensions/common/error_utils.h" | 113 #include "extensions/common/error_utils.h" |
| 112 #include "googleurl/src/gurl.h" | 114 #include "googleurl/src/gurl.h" |
| 113 #include "grit/generated_resources.h" | 115 #include "grit/generated_resources.h" |
| 114 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 116 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 115 #include "sync/api/sync_change.h" | 117 #include "sync/api/sync_change.h" |
| 116 #include "sync/api/sync_error_factory.h" | 118 #include "sync/api/sync_error_factory.h" |
| 117 #include "webkit/database/database_tracker.h" | 119 #include "webkit/database/database_tracker.h" |
| 118 #include "webkit/database/database_util.h" | 120 #include "webkit/database/database_util.h" |
| 119 | 121 |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 show_extensions_prompts_(true), | 371 show_extensions_prompts_(true), |
| 370 install_updates_when_idle_(true), | 372 install_updates_when_idle_(true), |
| 371 ready_(false), | 373 ready_(false), |
| 372 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 374 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 373 menu_manager_(profile), | 375 menu_manager_(profile), |
| 374 app_notification_manager_( | 376 app_notification_manager_( |
| 375 new extensions::AppNotificationManager(profile)), | 377 new extensions::AppNotificationManager(profile)), |
| 376 event_routers_initialized_(false), | 378 event_routers_initialized_(false), |
| 377 update_once_all_providers_are_ready_(false), | 379 update_once_all_providers_are_ready_(false), |
| 378 browser_terminating_(false), | 380 browser_terminating_(false), |
| 381 installs_delayed_(false), | |
| 379 app_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 382 app_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 380 extension_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 383 extension_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 381 app_shortcut_manager_(profile) { | 384 app_shortcut_manager_(profile) { |
| 382 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 385 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 383 | 386 |
| 384 // Figure out if extension installation should be enabled. | 387 // Figure out if extension installation should be enabled. |
| 385 if (command_line->HasSwitch(switches::kDisableExtensions) || | 388 if (command_line->HasSwitch(switches::kDisableExtensions) || |
| 386 profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { | 389 profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { |
| 387 extensions_enabled_ = false; | 390 extensions_enabled_ = false; |
| 388 } | 391 } |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 int include_mask = INCLUDE_ENABLED; | 586 int include_mask = INCLUDE_ENABLED; |
| 584 if (include_disabled) { | 587 if (include_disabled) { |
| 585 // Include blacklisted extensions here because there are hundreds of | 588 // Include blacklisted extensions here because there are hundreds of |
| 586 // callers of this function, and many might assume that this includes those | 589 // callers of this function, and many might assume that this includes those |
| 587 // that have been disabled due to blacklisting. | 590 // that have been disabled due to blacklisting. |
| 588 include_mask |= INCLUDE_DISABLED | INCLUDE_BLACKLISTED; | 591 include_mask |= INCLUDE_DISABLED | INCLUDE_BLACKLISTED; |
| 589 } | 592 } |
| 590 return GetExtensionById(id, include_mask); | 593 return GetExtensionById(id, include_mask); |
| 591 } | 594 } |
| 592 | 595 |
| 596 GURL ExtensionService::GetSiteForExtensionId(const std::string& extension_id) { | |
| 597 return content::SiteInstance::GetSiteForURL( | |
| 598 profile_, | |
| 599 Extension::GetBaseURLFromExtensionId(extension_id)); | |
| 600 } | |
| 601 | |
| 593 const Extension* ExtensionService::GetExtensionById( | 602 const Extension* ExtensionService::GetExtensionById( |
| 594 const std::string& id, int include_mask) const { | 603 const std::string& id, int include_mask) const { |
| 595 std::string lowercase_id = StringToLowerASCII(id); | 604 std::string lowercase_id = StringToLowerASCII(id); |
| 596 if (include_mask & INCLUDE_ENABLED) { | 605 if (include_mask & INCLUDE_ENABLED) { |
| 597 const Extension* extension = extensions_.GetByID(lowercase_id); | 606 const Extension* extension = extensions_.GetByID(lowercase_id); |
| 598 if (extension) | 607 if (extension) |
| 599 return extension; | 608 return extension; |
| 600 } | 609 } |
| 601 if (include_mask & INCLUDE_DISABLED) { | 610 if (include_mask & INCLUDE_DISABLED) { |
| 602 const Extension* extension = disabled_extensions_.GetByID(lowercase_id); | 611 const Extension* extension = disabled_extensions_.GetByID(lowercase_id); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 615 } | 624 } |
| 616 return NULL; | 625 return NULL; |
| 617 } | 626 } |
| 618 | 627 |
| 619 void ExtensionService::Init() { | 628 void ExtensionService::Init() { |
| 620 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 629 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 621 | 630 |
| 622 DCHECK(!ready_); // Can't redo init. | 631 DCHECK(!ready_); // Can't redo init. |
| 623 DCHECK_EQ(extensions_.size(), 0u); | 632 DCHECK_EQ(extensions_.size(), 0u); |
| 624 | 633 |
| 625 // TODO(mek): It might be cleaner to do the FinishIdleInstallInfo stuff here | 634 // TODO(mek): It might be cleaner to do the FinishDelayedInstallInfo stuff |
| 626 // instead of in installedloader | 635 // here instead of in installedloader. |
| 627 component_loader_->LoadAll(); | 636 component_loader_->LoadAll(); |
| 628 extensions::InstalledLoader(this).LoadAllExtensions(); | 637 extensions::InstalledLoader(this).LoadAllExtensions(); |
| 629 | 638 |
| 630 // The Sideload Wipeout effort takes place during load (see above), so once | 639 // The Sideload Wipeout effort takes place during load (see above), so once |
| 631 // that is done the flag can be set so that we don't have to check again. | 640 // that is done the flag can be set so that we don't have to check again. |
| 632 if (FeatureSwitch::sideload_wipeout()->IsEnabled()) | 641 if (FeatureSwitch::sideload_wipeout()->IsEnabled()) |
| 633 extension_prefs_->SetSideloadWipeoutDone(); | 642 extension_prefs_->SetSideloadWipeoutDone(); |
| 634 | 643 |
| 635 // If we are running in the import process, don't bother initializing the | 644 // If we are running in the import process, don't bother initializing the |
| 636 // extension service since this can interfere with the main browser process | 645 // extension service since this can interfere with the main browser process |
| 637 // that is already running an extension service for this profile. | 646 // that is already running an extension service for this profile. |
| 638 // TODO(aa): can we start up even less of ExtensionService? | 647 // TODO(aa): can we start up even less of ExtensionService? |
| 639 // http://crbug.com/107636 | 648 // http://crbug.com/107636 |
| 640 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kImport) && | 649 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kImport) && |
| 641 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kImportFromFile)) { | 650 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kImportFromFile)) { |
| 642 if (g_browser_process->profile_manager() && | 651 if (g_browser_process->profile_manager() && |
| 643 g_browser_process->profile_manager()->will_import()) { | 652 g_browser_process->profile_manager()->will_import()) { |
| 644 RegisterForImportFinished(); | 653 RegisterForImportFinished(); |
| 645 } else { | 654 } else { |
| 646 // TODO(erikkay) this should probably be deferred to a future point | 655 // TODO(erikkay) this should probably be deferred to a future point |
| 647 // rather than running immediately at startup. | 656 // rather than running immediately at startup. |
| 648 CheckForExternalUpdates(); | 657 CheckForExternalUpdates(); |
| 649 | 658 |
| 650 // TODO(erikkay) this should probably be deferred as well. | 659 // TODO(erikkay) this should probably be deferred as well. |
| 651 GarbageCollectExtensions(); | 660 GarbageCollectExtensions(); |
| 652 } | 661 } |
| 653 } | 662 } |
| 663 | |
| 664 if (extension_prefs_->NeedsStorageGarbageCollection()) { | |
| 665 GarbageCollectIsolatedStorage(); | |
| 666 extension_prefs_->SetNeedsStorageGarbageCollection(false); | |
| 667 } | |
| 654 } | 668 } |
| 655 | 669 |
| 656 bool ExtensionService::UpdateExtension(const std::string& id, | 670 bool ExtensionService::UpdateExtension(const std::string& id, |
| 657 const FilePath& extension_path, | 671 const FilePath& extension_path, |
| 658 const GURL& download_url, | 672 const GURL& download_url, |
| 659 CrxInstaller** out_crx_installer) { | 673 CrxInstaller** out_crx_installer) { |
| 660 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 674 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 661 if (browser_terminating_) { | 675 if (browser_terminating_) { |
| 662 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; | 676 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; |
| 663 // Leak the temp file at extension_path. We don't want to add to the disk | 677 // Leak the temp file at extension_path. We don't want to add to the disk |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 775 | 789 |
| 776 on_load_events_[extension_id] = events; | 790 on_load_events_[extension_id] = events; |
| 777 | 791 |
| 778 path = current_extension->path(); | 792 path = current_extension->path(); |
| 779 DisableExtension(extension_id, Extension::DISABLE_RELOAD); | 793 DisableExtension(extension_id, Extension::DISABLE_RELOAD); |
| 780 disabled_extension_paths_[extension_id] = path; | 794 disabled_extension_paths_[extension_id] = path; |
| 781 } else { | 795 } else { |
| 782 path = unloaded_extension_paths_[extension_id]; | 796 path = unloaded_extension_paths_[extension_id]; |
| 783 } | 797 } |
| 784 | 798 |
| 785 if (pending_extension_updates_.Contains(extension_id)) { | 799 if (delayed_updates_for_idle_.Contains(extension_id)) { |
| 786 FinishDelayedInstallation(extension_id); | 800 FinishDelayedInstallation(extension_id); |
| 787 return; | 801 return; |
| 788 } | 802 } |
| 789 | 803 |
| 790 // If we're reloading a component extension, use the component extension | 804 // If we're reloading a component extension, use the component extension |
| 791 // loader's reloader. | 805 // loader's reloader. |
| 792 if (component_loader_->Exists(extension_id)) { | 806 if (component_loader_->Exists(extension_id)) { |
| 793 component_loader_->Reload(extension_id); | 807 component_loader_->Reload(extension_id); |
| 794 return; | 808 return; |
| 795 } | 809 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 873 &extension_file_util::UninstallExtension, | 887 &extension_file_util::UninstallExtension, |
| 874 install_directory_, | 888 install_directory_, |
| 875 extension_id))) | 889 extension_id))) |
| 876 NOTREACHED(); | 890 NOTREACHED(); |
| 877 } | 891 } |
| 878 | 892 |
| 879 GURL launch_web_url_origin(extension->launch_web_url()); | 893 GURL launch_web_url_origin(extension->launch_web_url()); |
| 880 launch_web_url_origin = launch_web_url_origin.GetOrigin(); | 894 launch_web_url_origin = launch_web_url_origin.GetOrigin(); |
| 881 bool is_storage_isolated = extension->is_storage_isolated(); | 895 bool is_storage_isolated = extension->is_storage_isolated(); |
| 882 | 896 |
| 883 if (extension->is_hosted_app() && | 897 if (is_storage_isolated) { |
| 884 !profile_->GetExtensionSpecialStoragePolicy()-> | 898 BrowserContext::AsyncObliterateStoragePartition( |
| 885 IsStorageProtected(launch_web_url_origin)) { | 899 profile_, |
| 886 extensions::DataDeleter::StartDeleting( | 900 GetSiteForExtensionId(extension_id), |
| 887 profile_, extension_id, launch_web_url_origin, is_storage_isolated); | 901 base::Bind(&ExtensionService::OnNeedsToGarbageCollectIsolatedStorage, |
| 902 AsWeakPtr())); | |
| 903 } else { | |
| 904 if (extension->is_hosted_app() && | |
| 905 !profile_->GetExtensionSpecialStoragePolicy()-> | |
| 906 IsStorageProtected(launch_web_url_origin)) { | |
| 907 extensions::DataDeleter::StartDeleting( | |
| 908 profile_, extension_id, launch_web_url_origin); | |
| 909 } | |
| 910 extensions::DataDeleter::StartDeleting(profile_, extension_id, | |
| 911 extension->url()); | |
| 888 } | 912 } |
| 889 extensions::DataDeleter::StartDeleting( | |
| 890 profile_, extension_id, extension->url(), is_storage_isolated); | |
| 891 | 913 |
| 892 UntrackTerminatedExtension(extension_id); | 914 UntrackTerminatedExtension(extension_id); |
| 893 | 915 |
| 894 // Notify interested parties that we've uninstalled this extension. | 916 // Notify interested parties that we've uninstalled this extension. |
| 895 content::NotificationService::current()->Notify( | 917 content::NotificationService::current()->Notify( |
| 896 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, | 918 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, |
| 897 content::Source<Profile>(profile_), | 919 content::Source<Profile>(profile_), |
| 898 content::Details<const Extension>(extension)); | 920 content::Details<const Extension>(extension)); |
| 899 | 921 |
| 900 if (app_sync_bundle_.HasExtensionId(extension_id) && | 922 if (app_sync_bundle_.HasExtensionId(extension_id) && |
| 901 sync_change.sync_data().GetDataType() == syncer::APPS) { | 923 sync_change.sync_data().GetDataType() == syncer::APPS) { |
| 902 app_sync_bundle_.ProcessDeletion(extension_id, sync_change); | 924 app_sync_bundle_.ProcessDeletion(extension_id, sync_change); |
| 903 } else if (extension_sync_bundle_.HasExtensionId(extension_id) && | 925 } else if (extension_sync_bundle_.HasExtensionId(extension_id) && |
| 904 sync_change.sync_data().GetDataType() == syncer::EXTENSIONS) { | 926 sync_change.sync_data().GetDataType() == syncer::EXTENSIONS) { |
| 905 extension_sync_bundle_.ProcessDeletion(extension_id, sync_change); | 927 extension_sync_bundle_.ProcessDeletion(extension_id, sync_change); |
| 906 } | 928 } |
| 907 | 929 |
| 908 pending_extension_updates_.Remove(extension_id); | 930 delayed_updates_for_idle_.Remove(extension_id); |
| 931 delayed_installs_.Remove(extension_id); | |
| 909 | 932 |
| 910 // Track the uninstallation. | 933 // Track the uninstallation. |
| 911 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); | 934 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); |
| 912 | 935 |
| 913 return true; | 936 return true; |
| 914 } | 937 } |
| 915 | 938 |
| 916 bool ExtensionService::IsExtensionEnabled( | 939 bool ExtensionService::IsExtensionEnabled( |
| 917 const std::string& extension_id) const { | 940 const std::string& extension_id) const { |
| 918 if (extensions_.Contains(extension_id) || | 941 if (extensions_.Contains(extension_id) || |
| (...skipping 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2059 } | 2082 } |
| 2060 | 2083 |
| 2061 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> info( | 2084 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> info( |
| 2062 extension_prefs_->GetInstalledExtensionsInfo()); | 2085 extension_prefs_->GetInstalledExtensionsInfo()); |
| 2063 | 2086 |
| 2064 std::multimap<std::string, FilePath> extension_paths; | 2087 std::multimap<std::string, FilePath> extension_paths; |
| 2065 for (size_t i = 0; i < info->size(); ++i) | 2088 for (size_t i = 0; i < info->size(); ++i) |
| 2066 extension_paths.insert(std::make_pair(info->at(i)->extension_id, | 2089 extension_paths.insert(std::make_pair(info->at(i)->extension_id, |
| 2067 info->at(i)->extension_path)); | 2090 info->at(i)->extension_path)); |
| 2068 | 2091 |
| 2069 info = extension_prefs_->GetAllIdleInstallInfo(); | 2092 info = extension_prefs_->GetAllDelayedInstallInfo(); |
| 2070 for (size_t i = 0; i < info->size(); ++i) | 2093 for (size_t i = 0; i < info->size(); ++i) |
| 2071 extension_paths.insert(std::make_pair(info->at(i)->extension_id, | 2094 extension_paths.insert(std::make_pair(info->at(i)->extension_id, |
| 2072 info->at(i)->extension_path)); | 2095 info->at(i)->extension_path)); |
| 2073 | 2096 |
| 2074 if (!GetFileTaskRunner()->PostTask( | 2097 if (!GetFileTaskRunner()->PostTask( |
| 2075 FROM_HERE, | 2098 FROM_HERE, |
| 2076 base::Bind( | 2099 base::Bind( |
| 2077 &extension_file_util::GarbageCollectExtensions, | 2100 &extension_file_util::GarbageCollectExtensions, |
| 2078 install_directory_, | 2101 install_directory_, |
| 2079 extension_paths))) { | 2102 extension_paths))) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2191 const std::string old_version_string( | 2214 const std::string old_version_string( |
| 2192 extension_prefs_->GetVersionString(extension->id())); | 2215 extension_prefs_->GetVersionString(extension->id())); |
| 2193 const Version old_version(old_version_string); | 2216 const Version old_version(old_version_string); |
| 2194 | 2217 |
| 2195 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { | 2218 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { |
| 2196 VLOG(1) << "Component extension " << extension->name() << " (" | 2219 VLOG(1) << "Component extension " << extension->name() << " (" |
| 2197 << extension->id() << ") installing/upgrading from '" | 2220 << extension->id() << ") installing/upgrading from '" |
| 2198 << old_version_string << "' to " << extension->version()->GetString(); | 2221 << old_version_string << "' to " << extension->version()->GetString(); |
| 2199 | 2222 |
| 2200 AddNewOrUpdatedExtension(extension, | 2223 AddNewOrUpdatedExtension(extension, |
| 2201 syncer::StringOrdinal(), | 2224 Extension::ENABLED_COMPONENT, |
| 2202 Extension::ENABLED_COMPONENT); | 2225 syncer::StringOrdinal()); |
| 2203 return; | 2226 return; |
| 2204 } | 2227 } |
| 2205 | 2228 |
| 2206 AddExtension(extension); | 2229 AddExtension(extension); |
| 2207 } | 2230 } |
| 2208 | 2231 |
| 2209 void ExtensionService::InitializePermissions(const Extension* extension) { | 2232 void ExtensionService::InitializePermissions(const Extension* extension) { |
| 2210 // If the extension has used the optional permissions API, it will have a | 2233 // If the extension has used the optional permissions API, it will have a |
| 2211 // custom set of active permissions defined in the extension prefs. Here, | 2234 // custom set of active permissions defined in the extension prefs. Here, |
| 2212 // we update the extension's active permissions based on the prefs. | 2235 // we update the extension's active permissions based on the prefs. |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2449 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", | 2472 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", |
| 2450 extension->GetType(), 100); | 2473 extension->GetType(), 100); |
| 2451 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", | 2474 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", |
| 2452 extension->location(), Extension::NUM_LOCATIONS); | 2475 extension->location(), Extension::NUM_LOCATIONS); |
| 2453 } | 2476 } |
| 2454 | 2477 |
| 2455 // Certain extension locations are specific enough that we can | 2478 // Certain extension locations are specific enough that we can |
| 2456 // auto-acknowledge any extension that came from one of them. | 2479 // auto-acknowledge any extension that came from one of them. |
| 2457 if (extension->location() == Extension::EXTERNAL_POLICY_DOWNLOAD) | 2480 if (extension->location() == Extension::EXTERNAL_POLICY_DOWNLOAD) |
| 2458 AcknowledgeExternalExtension(extension->id()); | 2481 AcknowledgeExternalExtension(extension->id()); |
| 2459 | 2482 const Extension::State initial_state = |
| 2483 initial_enable ? Extension::ENABLED : Extension::DISABLED; | |
| 2460 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) { | 2484 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) { |
| 2461 extension_prefs_->SetIdleInstallInfo( | 2485 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, |
| 2462 extension, | 2486 page_ordinal); |
| 2463 initial_enable ? Extension::ENABLED : Extension::DISABLED, | |
| 2464 page_ordinal); | |
| 2465 | 2487 |
| 2466 // Transfer ownership of |extension|. | 2488 // Transfer ownership of |extension|. |
| 2467 pending_extension_updates_.Insert(extension); | 2489 delayed_updates_for_idle_.Insert(extension); |
| 2468 | 2490 |
| 2469 // Notify extension of available update. | 2491 // Notify extension of available update. |
| 2470 extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent( | 2492 extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent( |
| 2471 profile_, id, extension->manifest()->value()); | 2493 profile_, id, extension->manifest()->value()); |
| 2472 return; | 2494 return; |
| 2473 } | 2495 } |
| 2474 | 2496 |
| 2475 // Transfer ownership of |extension|. | 2497 if (installs_delayed()) { |
|
Charlie Reis
2012/12/10 23:22:28
Is this comment worth keeping?
awong
2012/12/11 01:18:32
I don't believe so.
| |
| 2476 AddNewOrUpdatedExtension( | 2498 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, |
| 2477 extension, | 2499 page_ordinal); |
| 2478 page_ordinal, | 2500 delayed_installs_.Insert(extension); |
| 2479 initial_enable ? Extension::ENABLED : Extension::DISABLED); | 2501 } else { |
| 2502 AddNewOrUpdatedExtension(extension, initial_state, page_ordinal); | |
| 2503 } | |
| 2480 } | 2504 } |
| 2481 | 2505 |
| 2482 void ExtensionService::AddNewOrUpdatedExtension( | 2506 void ExtensionService::AddNewOrUpdatedExtension( |
| 2483 const Extension* extension, | 2507 const Extension* extension, |
| 2484 const syncer::StringOrdinal& page_ordinal, | 2508 Extension::State initial_state, |
| 2485 Extension::State initial_state) { | 2509 const syncer::StringOrdinal& page_ordinal) { |
| 2486 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2510 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2487 | 2511 |
| 2488 extension_prefs_->OnExtensionInstalled( | 2512 extension_prefs_->OnExtensionInstalled( |
| 2489 extension, | 2513 extension, |
| 2490 initial_state, | 2514 initial_state, |
| 2491 page_ordinal); | 2515 page_ordinal); |
| 2492 | 2516 |
| 2493 // Unpacked extensions default to allowing file access, but if that has been | |
| 2494 // overridden, don't reset the value. | |
| 2495 if (Extension::ShouldAlwaysAllowFileAccess(extension->location()) && | |
| 2496 !extension_prefs_->HasAllowFileAccessSetting(extension->id())) { | |
| 2497 extension_prefs_->SetAllowFileAccess(extension->id(), true); | |
| 2498 } | |
| 2499 | |
| 2500 FinishInstallation(extension); | 2517 FinishInstallation(extension); |
| 2501 } | 2518 } |
| 2502 | 2519 |
| 2503 void ExtensionService::MaybeFinishDelayedInstallation( | 2520 void ExtensionService::MaybeFinishDelayedInstallation( |
| 2504 const std::string& extension_id) { | 2521 const std::string& extension_id) { |
| 2505 // Check if the extension already got updated. | 2522 // Check if the extension already got updated. |
| 2506 if (!pending_extension_updates_.Contains(extension_id)) | 2523 if (!delayed_updates_for_idle_.Contains(extension_id)) |
| 2507 return; | 2524 return; |
| 2508 // Check if the extension is idle. | 2525 // Check if the extension is idle. |
| 2509 if (!IsExtensionIdle(extension_id)) | 2526 if (!IsExtensionIdle(extension_id)) |
| 2510 return; | 2527 return; |
| 2511 | 2528 |
| 2512 FinishDelayedInstallation(extension_id); | 2529 FinishDelayedInstallation(extension_id); |
| 2513 } | 2530 } |
| 2514 | 2531 |
| 2515 void ExtensionService::FinishDelayedInstallation( | 2532 void ExtensionService::FinishDelayedInstallation( |
| 2516 const std::string& extension_id) { | 2533 const std::string& extension_id) { |
| 2517 scoped_refptr<const Extension> extension( | 2534 scoped_refptr<const Extension> extension( |
| 2518 GetPendingExtensionUpdate(extension_id)); | 2535 GetPendingExtensionUpdate(extension_id)); |
| 2519 CHECK(extension); | 2536 CHECK(extension); |
| 2520 pending_extension_updates_.Remove(extension_id); | 2537 delayed_updates_for_idle_.Remove(extension_id); |
| 2521 | 2538 |
| 2522 if (!extension_prefs_->FinishIdleInstallInfo(extension_id)) | 2539 if (!extension_prefs_->FinishDelayedInstallInfo(extension_id)) |
| 2523 NOTREACHED(); | 2540 NOTREACHED(); |
| 2524 | 2541 |
| 2525 FinishInstallation(extension); | 2542 FinishInstallation(extension); |
| 2526 } | 2543 } |
| 2527 | 2544 |
| 2528 void ExtensionService::FinishInstallation(const Extension* extension) { | 2545 void ExtensionService::FinishInstallation(const Extension* extension) { |
| 2529 content::NotificationService::current()->Notify( | 2546 content::NotificationService::current()->Notify( |
| 2530 chrome::NOTIFICATION_EXTENSION_INSTALLED, | 2547 chrome::NOTIFICATION_EXTENSION_INSTALLED, |
| 2531 content::Source<Profile>(profile_), | 2548 content::Source<Profile>(profile_), |
| 2532 content::Details<const Extension>(extension)); | 2549 content::Details<const Extension>(extension)); |
| 2533 | 2550 |
| 2534 bool unacknowledged_external = IsUnacknowledgedExternalExtension(extension); | 2551 bool unacknowledged_external = IsUnacknowledgedExternalExtension(extension); |
| 2535 | 2552 |
| 2553 // Unpacked extensions default to allowing file access, but if that has been | |
| 2554 // overridden, don't reset the value. | |
|
Charlie Reis
2012/12/10 23:22:28
This seems somewhat unrelated to the rest of the C
awong
2012/12/11 01:18:32
This is actually intentional. Without this change,
| |
| 2555 if (Extension::ShouldAlwaysAllowFileAccess(extension->location()) && | |
| 2556 !extension_prefs_->HasAllowFileAccessSetting(extension->id())) { | |
| 2557 extension_prefs_->SetAllowFileAccess(extension->id(), true); | |
| 2558 } | |
| 2559 | |
| 2536 AddExtension(extension); | 2560 AddExtension(extension); |
| 2537 | 2561 |
| 2538 // If this is a new external extension that was disabled, alert the user | 2562 // If this is a new external extension that was disabled, alert the user |
| 2539 // so he can reenable it. We do this last so that it has already been | 2563 // so he can reenable it. We do this last so that it has already been |
| 2540 // added to our list of extensions. | 2564 // added to our list of extensions. |
| 2541 if (unacknowledged_external) { | 2565 if (unacknowledged_external) { |
| 2542 UpdateExternalExtensionAlert(); | 2566 UpdateExternalExtensionAlert(); |
| 2543 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", | 2567 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", |
| 2544 EXTERNAL_EXTENSION_INSTALLED, | 2568 EXTERNAL_EXTENSION_INSTALLED, |
| 2545 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); | 2569 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); |
| 2546 } | 2570 } |
| 2547 } | 2571 } |
| 2548 | 2572 |
| 2549 const Extension* ExtensionService::GetPendingExtensionUpdate( | 2573 const Extension* ExtensionService::GetPendingExtensionUpdate( |
| 2550 const std::string& id) const { | 2574 const std::string& id) const { |
| 2551 return pending_extension_updates_.GetByID(id); | 2575 return delayed_updates_for_idle_.GetByID(id); |
| 2552 } | 2576 } |
| 2553 | 2577 |
| 2554 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { | 2578 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { |
| 2555 if (!terminated_extensions_.Contains(extension->id())) | 2579 if (!terminated_extensions_.Contains(extension->id())) |
| 2556 terminated_extensions_.Insert(make_scoped_refptr(extension)); | 2580 terminated_extensions_.Insert(make_scoped_refptr(extension)); |
| 2557 | 2581 |
| 2558 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE); | 2582 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE); |
| 2559 } | 2583 } |
| 2560 | 2584 |
| 2561 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { | 2585 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2787 break; | 2811 break; |
| 2788 } | 2812 } |
| 2789 case chrome::NOTIFICATION_IMPORT_FINISHED: { | 2813 case chrome::NOTIFICATION_IMPORT_FINISHED: { |
| 2790 InitAfterImport(); | 2814 InitAfterImport(); |
| 2791 break; | 2815 break; |
| 2792 } | 2816 } |
| 2793 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { | 2817 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { |
| 2794 extensions::ExtensionHost* host = | 2818 extensions::ExtensionHost* host = |
| 2795 content::Details<extensions::ExtensionHost>(details).ptr(); | 2819 content::Details<extensions::ExtensionHost>(details).ptr(); |
| 2796 std::string extension_id = host->extension_id(); | 2820 std::string extension_id = host->extension_id(); |
| 2797 if (pending_extension_updates_.Contains(extension_id)) { | 2821 if (delayed_updates_for_idle_.Contains(extension_id)) { |
| 2798 // We were waiting for this extension to become idle, it now might have, | 2822 // We were waiting for this extension to become idle, it now might have, |
| 2799 // so maybe finish installation. | 2823 // so maybe finish installation. |
| 2800 MessageLoop::current()->PostDelayedTask( | 2824 MessageLoop::current()->PostDelayedTask( |
| 2801 FROM_HERE, | 2825 FROM_HERE, |
| 2802 base::Bind(&ExtensionService::MaybeFinishDelayedInstallation, | 2826 base::Bind(&ExtensionService::MaybeFinishDelayedInstallation, |
| 2803 AsWeakPtr(), extension_id), | 2827 AsWeakPtr(), extension_id), |
| 2804 base::TimeDelta::FromSeconds(kUpdateIdleDelay)); | 2828 base::TimeDelta::FromSeconds(kUpdateIdleDelay)); |
| 2805 } | 2829 } |
| 2806 break; | 2830 break; |
| 2807 } | 2831 } |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3075 // Delay installation if the extension listens for the onUpdateAvailable | 3099 // Delay installation if the extension listens for the onUpdateAvailable |
| 3076 // event. | 3100 // event. |
| 3077 return system_->event_router()->ExtensionHasEventListener( | 3101 return system_->event_router()->ExtensionHasEventListener( |
| 3078 extension_id, kOnUpdateAvailableEvent); | 3102 extension_id, kOnUpdateAvailableEvent); |
| 3079 } else { | 3103 } else { |
| 3080 // Delay installation if the extension is not idle. | 3104 // Delay installation if the extension is not idle. |
| 3081 return !IsExtensionIdle(extension_id); | 3105 return !IsExtensionIdle(extension_id); |
| 3082 } | 3106 } |
| 3083 } | 3107 } |
| 3084 | 3108 |
| 3109 void ExtensionService::GarbageCollectIsolatedStorage() { | |
| 3110 scoped_ptr<base::hash_set<FilePath> > active_paths( | |
| 3111 new base::hash_set<FilePath>()); | |
| 3112 for (ExtensionSet::const_iterator it = extensions_.begin(); | |
| 3113 it != extensions_.end(); ++it) { | |
| 3114 if ((*it)->is_storage_isolated()) { | |
| 3115 active_paths->insert( | |
| 3116 BrowserContext::GetStoragePartitionForSite( | |
| 3117 profile_, | |
| 3118 GetSiteForExtensionId((*it)->id()))->GetPath()); | |
|
Charlie Reis
2012/12/10 23:22:28
Why is GetPath() needed? GetSiteForURL doesn't in
awong
2012/12/11 01:18:32
It's actually getting the path on the StorageParti
| |
| 3119 } | |
| 3120 } | |
| 3121 | |
| 3122 DCHECK(!installs_delayed()); | |
| 3123 set_installs_delayed(true); | |
| 3124 BrowserContext::GarbageCollectStoragePartitions( | |
| 3125 profile_, active_paths.Pass(), | |
| 3126 base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished, | |
| 3127 AsWeakPtr())); | |
| 3128 } | |
| 3129 | |
| 3130 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { | |
| 3131 set_installs_delayed(false); | |
| 3132 for (ExtensionSet::const_iterator it = delayed_installs_.begin(); | |
| 3133 it != delayed_installs_.end(); | |
| 3134 ++it) { | |
| 3135 FinishDelayedInstallation((*it)->id()); | |
| 3136 } | |
| 3137 for (ExtensionSet::const_iterator it = delayed_updates_for_idle_.begin(); | |
| 3138 it != delayed_updates_for_idle_.end(); | |
| 3139 ++it) { | |
| 3140 MaybeFinishDelayedInstallation((*it)->id()); | |
| 3141 } | |
| 3142 delayed_installs_.Clear(); | |
| 3143 } | |
| 3144 | |
| 3145 void ExtensionService::OnNeedsToGarbageCollectIsolatedStorage() { | |
| 3146 extension_prefs_->SetNeedsStorageGarbageCollection(true); | |
| 3147 } | |
| 3148 | |
| 3085 void ExtensionService::OnBlacklistUpdated() { | 3149 void ExtensionService::OnBlacklistUpdated() { |
| 3086 blacklist_->GetBlacklistedIDs( | 3150 blacklist_->GetBlacklistedIDs( |
| 3087 GenerateInstalledExtensionsSet()->GetIDs(), | 3151 GenerateInstalledExtensionsSet()->GetIDs(), |
| 3088 base::Bind(&ExtensionService::ManageBlacklist, | 3152 base::Bind(&ExtensionService::ManageBlacklist, |
| 3089 AsWeakPtr(), | 3153 AsWeakPtr(), |
| 3090 blacklisted_extensions_.GetIDs())); | 3154 blacklisted_extensions_.GetIDs())); |
| 3091 } | 3155 } |
| 3092 | 3156 |
| 3093 void ExtensionService::ManageBlacklist( | 3157 void ExtensionService::ManageBlacklist( |
| 3094 const std::set<std::string>& old_blacklisted_ids, | 3158 const std::set<std::string>& old_blacklisted_ids, |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 3122 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); | 3186 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); |
| 3123 DCHECK(extension); | 3187 DCHECK(extension); |
| 3124 if (!extension) | 3188 if (!extension) |
| 3125 continue; | 3189 continue; |
| 3126 blacklisted_extensions_.Insert(extension); | 3190 blacklisted_extensions_.Insert(extension); |
| 3127 UnloadExtension(*it, extension_misc::UNLOAD_REASON_BLACKLIST); | 3191 UnloadExtension(*it, extension_misc::UNLOAD_REASON_BLACKLIST); |
| 3128 } | 3192 } |
| 3129 | 3193 |
| 3130 IdentifyAlertableExtensions(); | 3194 IdentifyAlertableExtensions(); |
| 3131 } | 3195 } |
| OLD | NEW |