| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 16 matching lines...) Expand all Loading... |
| 27 #include "base/version.h" | 27 #include "base/version.h" |
| 28 #include "chrome/browser/browser_process.h" | 28 #include "chrome/browser/browser_process.h" |
| 29 #include "chrome/browser/chrome_notification_types.h" | 29 #include "chrome/browser/chrome_notification_types.h" |
| 30 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 30 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
| 31 #include "chrome/browser/extensions/component_loader.h" | 31 #include "chrome/browser/extensions/component_loader.h" |
| 32 #include "chrome/browser/extensions/crx_installer.h" | 32 #include "chrome/browser/extensions/crx_installer.h" |
| 33 #include "chrome/browser/extensions/data_deleter.h" | 33 #include "chrome/browser/extensions/data_deleter.h" |
| 34 #include "chrome/browser/extensions/extension_disabled_ui.h" | 34 #include "chrome/browser/extensions/extension_disabled_ui.h" |
| 35 #include "chrome/browser/extensions/extension_error_reporter.h" | 35 #include "chrome/browser/extensions/extension_error_reporter.h" |
| 36 #include "chrome/browser/extensions/extension_error_ui.h" | 36 #include "chrome/browser/extensions/extension_error_ui.h" |
| 37 #include "chrome/browser/extensions/extension_garbage_collector.h" |
| 37 #include "chrome/browser/extensions/extension_install_ui.h" | 38 #include "chrome/browser/extensions/extension_install_ui.h" |
| 38 #include "chrome/browser/extensions/extension_special_storage_policy.h" | 39 #include "chrome/browser/extensions/extension_special_storage_policy.h" |
| 39 #include "chrome/browser/extensions/extension_sync_service.h" | 40 #include "chrome/browser/extensions/extension_sync_service.h" |
| 40 #include "chrome/browser/extensions/extension_util.h" | 41 #include "chrome/browser/extensions/extension_util.h" |
| 41 #include "chrome/browser/extensions/external_install_ui.h" | 42 #include "chrome/browser/extensions/external_install_ui.h" |
| 42 #include "chrome/browser/extensions/external_provider_impl.h" | 43 #include "chrome/browser/extensions/external_provider_impl.h" |
| 43 #include "chrome/browser/extensions/install_verifier.h" | 44 #include "chrome/browser/extensions/install_verifier.h" |
| 44 #include "chrome/browser/extensions/installed_loader.h" | 45 #include "chrome/browser/extensions/installed_loader.h" |
| 45 #include "chrome/browser/extensions/pending_extension_manager.h" | 46 #include "chrome/browser/extensions/pending_extension_manager.h" |
| 46 #include "chrome/browser/extensions/permissions_updater.h" | 47 #include "chrome/browser/extensions/permissions_updater.h" |
| 47 #include "chrome/browser/extensions/unpacked_installer.h" | 48 #include "chrome/browser/extensions/unpacked_installer.h" |
| 48 #include "chrome/browser/extensions/updater/extension_cache.h" | 49 #include "chrome/browser/extensions/updater/extension_cache.h" |
| 49 #include "chrome/browser/extensions/updater/extension_updater.h" | 50 #include "chrome/browser/extensions/updater/extension_updater.h" |
| 50 #include "chrome/browser/profiles/profile.h" | 51 #include "chrome/browser/profiles/profile.h" |
| 51 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | 52 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" |
| 52 #include "chrome/browser/ui/webui/favicon_source.h" | 53 #include "chrome/browser/ui/webui/favicon_source.h" |
| 53 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" | 54 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" |
| 54 #include "chrome/browser/ui/webui/theme_source.h" | 55 #include "chrome/browser/ui/webui/theme_source.h" |
| 55 #include "chrome/common/chrome_switches.h" | 56 #include "chrome/common/chrome_switches.h" |
| 56 #include "chrome/common/crash_keys.h" | 57 #include "chrome/common/crash_keys.h" |
| 57 #include "chrome/common/extensions/extension_constants.h" | 58 #include "chrome/common/extensions/extension_constants.h" |
| 58 #include "chrome/common/extensions/extension_file_util.h" | 59 #include "chrome/common/extensions/extension_file_util.h" |
| 59 #include "chrome/common/extensions/features/feature_channel.h" | 60 #include "chrome/common/extensions/features/feature_channel.h" |
| 60 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" | |
| 61 #include "chrome/common/extensions/manifest_url_handler.h" | 61 #include "chrome/common/extensions/manifest_url_handler.h" |
| 62 #include "chrome/common/pref_names.h" | 62 #include "chrome/common/pref_names.h" |
| 63 #include "chrome/common/url_constants.h" | 63 #include "chrome/common/url_constants.h" |
| 64 #include "components/startup_metric_utils/startup_metric_utils.h" | 64 #include "components/startup_metric_utils/startup_metric_utils.h" |
| 65 #include "content/public/browser/browser_thread.h" | 65 #include "content/public/browser/browser_thread.h" |
| 66 #include "content/public/browser/devtools_agent_host.h" | 66 #include "content/public/browser/devtools_agent_host.h" |
| 67 #include "content/public/browser/notification_service.h" | 67 #include "content/public/browser/notification_service.h" |
| 68 #include "content/public/browser/notification_types.h" | 68 #include "content/public/browser/notification_types.h" |
| 69 #include "content/public/browser/render_process_host.h" | 69 #include "content/public/browser/render_process_host.h" |
| 70 #include "content/public/browser/storage_partition.h" | 70 #include "content/public/browser/storage_partition.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 EXTERNAL_EXTENSION_UNINSTALLED, | 140 EXTERNAL_EXTENSION_UNINSTALLED, |
| 141 EXTERNAL_EXTENSION_BUCKET_BOUNDARY, | 141 EXTERNAL_EXTENSION_BUCKET_BOUNDARY, |
| 142 }; | 142 }; |
| 143 | 143 |
| 144 // Prompt the user this many times before considering an extension acknowledged. | 144 // Prompt the user this many times before considering an extension acknowledged. |
| 145 static const int kMaxExtensionAcknowledgePromptCount = 3; | 145 static const int kMaxExtensionAcknowledgePromptCount = 3; |
| 146 | 146 |
| 147 // Wait this many seconds after an extensions becomes idle before updating it. | 147 // Wait this many seconds after an extensions becomes idle before updating it. |
| 148 static const int kUpdateIdleDelay = 5; | 148 static const int kUpdateIdleDelay = 5; |
| 149 | 149 |
| 150 // Wait this many seconds before trying to garbage collect extensions again. | |
| 151 static const int kGarbageCollectRetryDelay = 30; | |
| 152 | |
| 153 // Wait this many seconds after startup to see if there are any extensions | |
| 154 // which can be garbage collected. | |
| 155 static const int kGarbageCollectStartupDelay = 30; | |
| 156 | |
| 157 static bool IsSharedModule(const Extension* extension) { | 150 static bool IsSharedModule(const Extension* extension) { |
| 158 return SharedModuleInfo::IsSharedModule(extension); | 151 return SharedModuleInfo::IsSharedModule(extension); |
| 159 } | 152 } |
| 160 | 153 |
| 161 static bool IsCWSSharedModule(const Extension* extension) { | 154 static bool IsCWSSharedModule(const Extension* extension) { |
| 162 return extension->from_webstore() && IsSharedModule(extension); | 155 return extension->from_webstore() && IsSharedModule(extension); |
| 163 } | 156 } |
| 164 | 157 |
| 165 class SharedModuleProvider : public extensions::ManagementPolicy::Provider { | 158 class SharedModuleProvider : public extensions::ManagementPolicy::Provider { |
| 166 public: | 159 public: |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 registry_(extensions::ExtensionRegistry::Get(profile)), | 357 registry_(extensions::ExtensionRegistry::Get(profile)), |
| 365 pending_extension_manager_(*this), | 358 pending_extension_manager_(*this), |
| 366 install_directory_(install_directory), | 359 install_directory_(install_directory), |
| 367 extensions_enabled_(extensions_enabled), | 360 extensions_enabled_(extensions_enabled), |
| 368 show_extensions_prompts_(true), | 361 show_extensions_prompts_(true), |
| 369 install_updates_when_idle_(true), | 362 install_updates_when_idle_(true), |
| 370 ready_(ready), | 363 ready_(ready), |
| 371 update_once_all_providers_are_ready_(false), | 364 update_once_all_providers_are_ready_(false), |
| 372 browser_terminating_(false), | 365 browser_terminating_(false), |
| 373 installs_delayed_for_gc_(false), | 366 installs_delayed_for_gc_(false), |
| 374 is_first_run_(false) { | 367 is_first_run_(false), |
| 375 #if defined(OS_CHROMEOS) | 368 garbage_collector_(new extensions::ExtensionGarbageCollector(this)) { |
| 376 disable_garbage_collection_ = false; | |
| 377 #endif | |
| 378 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 369 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 379 | 370 |
| 380 // Figure out if extension installation should be enabled. | 371 // Figure out if extension installation should be enabled. |
| 381 if (extensions::ExtensionsBrowserClient::Get()->AreExtensionsDisabled( | 372 if (extensions::ExtensionsBrowserClient::Get()->AreExtensionsDisabled( |
| 382 *command_line, profile)) | 373 *command_line, profile)) |
| 383 extensions_enabled_ = false; | 374 extensions_enabled_ = false; |
| 384 | 375 |
| 385 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 376 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
| 386 content::NotificationService::AllBrowserContextsAndSources()); | 377 content::NotificationService::AllBrowserContextsAndSources()); |
| 387 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, | 378 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad", | 545 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad", |
| 555 delayed_info2->size() - delayed_info->size()); | 546 delayed_info2->size() - delayed_info->size()); |
| 556 | 547 |
| 557 SetReadyAndNotifyListeners(); | 548 SetReadyAndNotifyListeners(); |
| 558 | 549 |
| 559 // TODO(erikkay) this should probably be deferred to a future point | 550 // TODO(erikkay) this should probably be deferred to a future point |
| 560 // rather than running immediately at startup. | 551 // rather than running immediately at startup. |
| 561 CheckForExternalUpdates(); | 552 CheckForExternalUpdates(); |
| 562 | 553 |
| 563 MaybeBootstrapVerifier(); | 554 MaybeBootstrapVerifier(); |
| 564 base::MessageLoop::current()->PostDelayedTask( | |
| 565 FROM_HERE, | |
| 566 base::Bind(&ExtensionService::GarbageCollectExtensions, AsWeakPtr()), | |
| 567 base::TimeDelta::FromSeconds(kGarbageCollectStartupDelay)); | |
| 568 | |
| 569 if (extension_prefs_->NeedsStorageGarbageCollection()) { | |
| 570 GarbageCollectIsolatedStorage(); | |
| 571 extension_prefs_->SetNeedsStorageGarbageCollection(false); | |
| 572 } | |
| 573 system_->management_policy()->RegisterProvider( | 555 system_->management_policy()->RegisterProvider( |
| 574 shared_module_policy_provider_.get()); | 556 shared_module_policy_provider_.get()); |
| 575 | 557 |
| 576 LoadGreylistFromPrefs(); | 558 LoadGreylistFromPrefs(); |
| 577 } | 559 } |
| 578 | 560 |
| 579 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime", | 561 UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime", |
| 580 base::Time::Now() - begin_time); | 562 base::Time::Now() - begin_time); |
| 581 } | 563 } |
| 582 | 564 |
| (...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1660 void ExtensionService::ReloadExtensionsForTest() { | 1642 void ExtensionService::ReloadExtensionsForTest() { |
| 1661 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit | 1643 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit |
| 1662 // warning about calling test code in production. | 1644 // warning about calling test code in production. |
| 1663 UnloadAllExtensionsInternal(); | 1645 UnloadAllExtensionsInternal(); |
| 1664 component_loader_->LoadAll(); | 1646 component_loader_->LoadAll(); |
| 1665 extensions::InstalledLoader(this).LoadAllExtensions(); | 1647 extensions::InstalledLoader(this).LoadAllExtensions(); |
| 1666 // Don't call SetReadyAndNotifyListeners() since tests call this multiple | 1648 // Don't call SetReadyAndNotifyListeners() since tests call this multiple |
| 1667 // times. | 1649 // times. |
| 1668 } | 1650 } |
| 1669 | 1651 |
| 1670 void ExtensionService::GarbageCollectExtensions() { | |
| 1671 #if defined(OS_CHROMEOS) | |
| 1672 if (disable_garbage_collection_) | |
| 1673 return; | |
| 1674 #endif | |
| 1675 | |
| 1676 if (extension_prefs_->pref_service()->ReadOnly()) | |
| 1677 return; | |
| 1678 | |
| 1679 bool clean_temp_dir = true; | |
| 1680 | |
| 1681 if (pending_extension_manager()->HasPendingExtensions()) { | |
| 1682 // Don't garbage collect temp dir while there are pending installations, | |
| 1683 // which may be using the temporary installation directory. Try to garbage | |
| 1684 // collect again later. | |
| 1685 clean_temp_dir = false; | |
| 1686 base::MessageLoop::current()->PostDelayedTask( | |
| 1687 FROM_HERE, | |
| 1688 base::Bind(&ExtensionService::GarbageCollectExtensions, AsWeakPtr()), | |
| 1689 base::TimeDelta::FromSeconds(kGarbageCollectRetryDelay)); | |
| 1690 } | |
| 1691 | |
| 1692 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> info( | |
| 1693 extension_prefs_->GetInstalledExtensionsInfo()); | |
| 1694 | |
| 1695 std::multimap<std::string, base::FilePath> extension_paths; | |
| 1696 for (size_t i = 0; i < info->size(); ++i) | |
| 1697 extension_paths.insert(std::make_pair(info->at(i)->extension_id, | |
| 1698 info->at(i)->extension_path)); | |
| 1699 | |
| 1700 info = extension_prefs_->GetAllDelayedInstallInfo(); | |
| 1701 for (size_t i = 0; i < info->size(); ++i) | |
| 1702 extension_paths.insert(std::make_pair(info->at(i)->extension_id, | |
| 1703 info->at(i)->extension_path)); | |
| 1704 | |
| 1705 if (!GetFileTaskRunner()->PostTask( | |
| 1706 FROM_HERE, | |
| 1707 base::Bind( | |
| 1708 &extension_file_util::GarbageCollectExtensions, | |
| 1709 install_directory_, | |
| 1710 extension_paths, | |
| 1711 clean_temp_dir))) { | |
| 1712 NOTREACHED(); | |
| 1713 } | |
| 1714 } | |
| 1715 | |
| 1716 void ExtensionService::SetReadyAndNotifyListeners() { | 1652 void ExtensionService::SetReadyAndNotifyListeners() { |
| 1717 ready_->Signal(); | 1653 ready_->Signal(); |
| 1718 content::NotificationService::current()->Notify( | 1654 content::NotificationService::current()->Notify( |
| 1719 chrome::NOTIFICATION_EXTENSIONS_READY, | 1655 chrome::NOTIFICATION_EXTENSIONS_READY, |
| 1720 content::Source<Profile>(profile_), | 1656 content::Source<Profile>(profile_), |
| 1721 content::NotificationService::NoDetails()); | 1657 content::NotificationService::NoDetails()); |
| 1722 } | 1658 } |
| 1723 | 1659 |
| 1724 void ExtensionService::OnLoadedInstalledExtensions() { | 1660 void ExtensionService::OnLoadedInstalledExtensions() { |
| 1725 if (updater_) | 1661 if (updater_) |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2188 // Transfer ownership of |extension|. | 2124 // Transfer ownership of |extension|. |
| 2189 delayed_installs_.Insert(extension); | 2125 delayed_installs_.Insert(extension); |
| 2190 | 2126 |
| 2191 // Notify observers that app update is available. | 2127 // Notify observers that app update is available. |
| 2192 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, | 2128 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, |
| 2193 OnAppUpdateAvailable(extension)); | 2129 OnAppUpdateAvailable(extension)); |
| 2194 return; | 2130 return; |
| 2195 } | 2131 } |
| 2196 | 2132 |
| 2197 ImportStatus status = SatisfyImports(extension); | 2133 ImportStatus status = SatisfyImports(extension); |
| 2198 if (installs_delayed_for_gc()) { | 2134 if (installs_delayed_for_gc_) { |
| 2199 extension_prefs_->SetDelayedInstallInfo( | 2135 extension_prefs_->SetDelayedInstallInfo( |
| 2200 extension, | 2136 extension, |
| 2201 initial_state, | 2137 initial_state, |
| 2202 blacklisted_for_malware, | 2138 blacklisted_for_malware, |
| 2203 extensions::ExtensionPrefs::DELAY_REASON_GC, | 2139 extensions::ExtensionPrefs::DELAY_REASON_GC, |
| 2204 page_ordinal, | 2140 page_ordinal, |
| 2205 install_parameter); | 2141 install_parameter); |
| 2206 delayed_installs_.Insert(extension); | 2142 delayed_installs_.Insert(extension); |
| 2207 } else if (status != IMPORT_STATUS_OK) { | 2143 } else if (status != IMPORT_STATUS_OK) { |
| 2208 if (status == IMPORT_STATUS_UNSATISFIED) { | 2144 if (status == IMPORT_STATUS_UNSATISFIED) { |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2650 // Delay installation if the extension listens for the onUpdateAvailable | 2586 // Delay installation if the extension listens for the onUpdateAvailable |
| 2651 // event. | 2587 // event. |
| 2652 return system_->event_router()->ExtensionHasEventListener( | 2588 return system_->event_router()->ExtensionHasEventListener( |
| 2653 extension_id, kOnUpdateAvailableEvent); | 2589 extension_id, kOnUpdateAvailableEvent); |
| 2654 } else { | 2590 } else { |
| 2655 // Delay installation if the extension is not idle. | 2591 // Delay installation if the extension is not idle. |
| 2656 return !extensions::util::IsExtensionIdle(extension_id, profile_); | 2592 return !extensions::util::IsExtensionIdle(extension_id, profile_); |
| 2657 } | 2593 } |
| 2658 } | 2594 } |
| 2659 | 2595 |
| 2660 void ExtensionService::GarbageCollectIsolatedStorage() { | 2596 void ExtensionService::OnGarbageCollectIsolatedStorageStart() { |
| 2661 scoped_ptr<base::hash_set<base::FilePath> > active_paths( | 2597 DCHECK(!installs_delayed_for_gc_); |
| 2662 new base::hash_set<base::FilePath>()); | 2598 installs_delayed_for_gc_ = true; |
| 2663 const ExtensionSet& extensions = registry_->enabled_extensions(); | |
| 2664 for (ExtensionSet::const_iterator it = extensions.begin(); | |
| 2665 it != extensions.end(); ++it) { | |
| 2666 if (extensions::AppIsolationInfo::HasIsolatedStorage(it->get())) { | |
| 2667 active_paths->insert(BrowserContext::GetStoragePartitionForSite( | |
| 2668 profile_, | |
| 2669 extensions::util::GetSiteForExtensionId( | |
| 2670 (*it)->id(), profile()))->GetPath()); | |
| 2671 } | |
| 2672 } | |
| 2673 | |
| 2674 // The data of ephemeral apps can outlive their cache lifetime. Ensure | |
| 2675 // they are not garbage collected. | |
| 2676 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> evicted_apps_info( | |
| 2677 extension_prefs_->GetEvictedEphemeralAppsInfo()); | |
| 2678 for (size_t i = 0; i < evicted_apps_info->size(); ++i) { | |
| 2679 extensions::ExtensionInfo* info = evicted_apps_info->at(i).get(); | |
| 2680 if (extensions::util::HasIsolatedStorage(*info)) { | |
| 2681 active_paths->insert(BrowserContext::GetStoragePartitionForSite( | |
| 2682 profile_, | |
| 2683 extensions::util::GetSiteForExtensionId( | |
| 2684 info->extension_id, profile()))->GetPath()); | |
| 2685 } | |
| 2686 } | |
| 2687 | |
| 2688 DCHECK(!installs_delayed_for_gc()); | |
| 2689 set_installs_delayed_for_gc(true); | |
| 2690 BrowserContext::GarbageCollectStoragePartitions( | |
| 2691 profile_, active_paths.Pass(), | |
| 2692 base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished, | |
| 2693 AsWeakPtr())); | |
| 2694 } | 2599 } |
| 2695 | 2600 |
| 2696 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { | 2601 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { |
| 2697 set_installs_delayed_for_gc(false); | 2602 DCHECK(installs_delayed_for_gc_); |
| 2603 installs_delayed_for_gc_ = false; |
| 2698 MaybeFinishDelayedInstallations(); | 2604 MaybeFinishDelayedInstallations(); |
| 2699 } | 2605 } |
| 2700 | 2606 |
| 2701 void ExtensionService::MaybeFinishDelayedInstallations() { | 2607 void ExtensionService::MaybeFinishDelayedInstallations() { |
| 2702 std::vector<std::string> to_be_installed; | 2608 std::vector<std::string> to_be_installed; |
| 2703 for (ExtensionSet::const_iterator it = delayed_installs_.begin(); | 2609 for (ExtensionSet::const_iterator it = delayed_installs_.begin(); |
| 2704 it != delayed_installs_.end(); | 2610 it != delayed_installs_.end(); |
| 2705 ++it) { | 2611 ++it) { |
| 2706 to_be_installed.push_back((*it)->id()); | 2612 to_be_installed.push_back((*it)->id()); |
| 2707 } | 2613 } |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2865 void ExtensionService::UnloadAllExtensionsInternal() { | 2771 void ExtensionService::UnloadAllExtensionsInternal() { |
| 2866 profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions(); | 2772 profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions(); |
| 2867 | 2773 |
| 2868 registry_->ClearAll(); | 2774 registry_->ClearAll(); |
| 2869 system_->runtime_data()->ClearAll(); | 2775 system_->runtime_data()->ClearAll(); |
| 2870 | 2776 |
| 2871 // TODO(erikkay) should there be a notification for this? We can't use | 2777 // TODO(erikkay) should there be a notification for this? We can't use |
| 2872 // EXTENSION_UNLOADED since that implies that the extension has been disabled | 2778 // EXTENSION_UNLOADED since that implies that the extension has been disabled |
| 2873 // or uninstalled. | 2779 // or uninstalled. |
| 2874 } | 2780 } |
| OLD | NEW |