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 <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 #include "chrome/common/extensions/manifest.h" | 102 #include "chrome/common/extensions/manifest.h" |
| 103 #include "chrome/common/pref_names.h" | 103 #include "chrome/common/pref_names.h" |
| 104 #include "chrome/common/url_constants.h" | 104 #include "chrome/common/url_constants.h" |
| 105 #include "content/public/browser/browser_thread.h" | 105 #include "content/public/browser/browser_thread.h" |
| 106 #include "content/public/browser/devtools_agent_host_registry.h" | 106 #include "content/public/browser/devtools_agent_host_registry.h" |
| 107 #include "content/public/browser/devtools_manager.h" | 107 #include "content/public/browser/devtools_manager.h" |
| 108 #include "content/public/browser/notification_service.h" | 108 #include "content/public/browser/notification_service.h" |
| 109 #include "content/public/browser/notification_types.h" | 109 #include "content/public/browser/notification_types.h" |
| 110 #include "content/public/browser/plugin_service.h" | 110 #include "content/public/browser/plugin_service.h" |
| 111 #include "content/public/browser/render_process_host.h" | 111 #include "content/public/browser/render_process_host.h" |
| 112 #include "content/public/browser/storage_partition.h" | |
| 112 #include "content/public/common/pepper_plugin_info.h" | 113 #include "content/public/common/pepper_plugin_info.h" |
| 113 #include "extensions/common/error_utils.h" | 114 #include "extensions/common/error_utils.h" |
| 114 #include "googleurl/src/gurl.h" | 115 #include "googleurl/src/gurl.h" |
| 115 #include "grit/generated_resources.h" | 116 #include "grit/generated_resources.h" |
| 116 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 117 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 117 #include "sync/api/sync_change.h" | 118 #include "sync/api/sync_change.h" |
| 118 #include "sync/api/sync_error_factory.h" | 119 #include "sync/api/sync_error_factory.h" |
| 119 #include "webkit/database/database_tracker.h" | 120 #include "webkit/database/database_tracker.h" |
| 120 #include "webkit/database/database_util.h" | 121 #include "webkit/database/database_util.h" |
| 121 | 122 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 | 198 |
| 198 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { | 199 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { |
| 199 } | 200 } |
| 200 | 201 |
| 201 ExtensionService::NaClModuleInfo::NaClModuleInfo() { | 202 ExtensionService::NaClModuleInfo::NaClModuleInfo() { |
| 202 } | 203 } |
| 203 | 204 |
| 204 ExtensionService::NaClModuleInfo::~NaClModuleInfo() { | 205 ExtensionService::NaClModuleInfo::~NaClModuleInfo() { |
| 205 } | 206 } |
| 206 | 207 |
| 208 ExtensionService::PendingInstall::PendingInstall( | |
| 209 const extensions::Extension* extension, | |
| 210 const syncer::StringOrdinal& page_ordinal, | |
| 211 bool has_requirement_errors, | |
| 212 bool wait_for_idle) | |
| 213 : extension(extension), | |
| 214 page_ordinal(page_ordinal), | |
| 215 has_requirement_errors(has_requirement_errors), | |
| 216 wait_for_idle(wait_for_idle) { | |
| 217 } | |
| 218 | |
| 219 ExtensionService::PendingInstall::~PendingInstall() { | |
| 220 } | |
| 221 | |
| 207 // ExtensionService. | 222 // ExtensionService. |
| 208 | 223 |
| 209 const char ExtensionService::kInstallDirectoryName[] = "Extensions"; | 224 const char ExtensionService::kInstallDirectoryName[] = "Extensions"; |
| 210 | 225 |
| 211 const char ExtensionService::kLocalAppSettingsDirectoryName[] = | 226 const char ExtensionService::kLocalAppSettingsDirectoryName[] = |
| 212 "Local App Settings"; | 227 "Local App Settings"; |
| 213 const char ExtensionService::kLocalExtensionSettingsDirectoryName[] = | 228 const char ExtensionService::kLocalExtensionSettingsDirectoryName[] = |
| 214 "Local Extension Settings"; | 229 "Local Extension Settings"; |
| 215 const char ExtensionService::kSyncAppSettingsDirectoryName[] = | 230 const char ExtensionService::kSyncAppSettingsDirectoryName[] = |
| 216 "Sync App Settings"; | 231 "Sync App Settings"; |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 show_extensions_prompts_(true), | 382 show_extensions_prompts_(true), |
| 368 install_updates_when_idle_(true), | 383 install_updates_when_idle_(true), |
| 369 ready_(false), | 384 ready_(false), |
| 370 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 385 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 371 menu_manager_(profile), | 386 menu_manager_(profile), |
| 372 app_notification_manager_( | 387 app_notification_manager_( |
| 373 new extensions::AppNotificationManager(profile)), | 388 new extensions::AppNotificationManager(profile)), |
| 374 event_routers_initialized_(false), | 389 event_routers_initialized_(false), |
| 375 update_once_all_providers_are_ready_(false), | 390 update_once_all_providers_are_ready_(false), |
| 376 browser_terminating_(false), | 391 browser_terminating_(false), |
| 392 delay_all_installs_(false), | |
| 377 app_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 393 app_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 378 extension_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 394 extension_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 379 app_shortcut_manager_(profile) { | 395 app_shortcut_manager_(profile) { |
| 380 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 396 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 381 | 397 |
| 382 // Figure out if extension installation should be enabled. | 398 // Figure out if extension installation should be enabled. |
| 383 if (command_line->HasSwitch(switches::kDisableExtensions) || | 399 if (command_line->HasSwitch(switches::kDisableExtensions) || |
| 384 profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { | 400 profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { |
| 385 extensions_enabled_ = false; | 401 extensions_enabled_ = false; |
| 386 } | 402 } |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 611 RegisterForImportFinished(); | 627 RegisterForImportFinished(); |
| 612 } else { | 628 } else { |
| 613 // TODO(erikkay) this should probably be deferred to a future point | 629 // TODO(erikkay) this should probably be deferred to a future point |
| 614 // rather than running immediately at startup. | 630 // rather than running immediately at startup. |
| 615 CheckForExternalUpdates(); | 631 CheckForExternalUpdates(); |
| 616 | 632 |
| 617 // TODO(erikkay) this should probably be deferred as well. | 633 // TODO(erikkay) this should probably be deferred as well. |
| 618 GarbageCollectExtensions(); | 634 GarbageCollectExtensions(); |
| 619 } | 635 } |
| 620 } | 636 } |
| 637 | |
| 638 if (extension_prefs_->NeedsStorageGarbageCollection()) { | |
| 639 GarbageCollectIsolatedStorage(); | |
| 640 extension_prefs_->SetNeedsStorageGarbageCollection(false); | |
| 641 } | |
| 621 } | 642 } |
| 622 | 643 |
| 623 bool ExtensionService::UpdateExtension(const std::string& id, | 644 bool ExtensionService::UpdateExtension(const std::string& id, |
| 624 const FilePath& extension_path, | 645 const FilePath& extension_path, |
| 625 const GURL& download_url, | 646 const GURL& download_url, |
| 626 CrxInstaller** out_crx_installer) { | 647 CrxInstaller** out_crx_installer) { |
| 627 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 648 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 628 if (browser_terminating_) { | 649 if (browser_terminating_) { |
| 629 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; | 650 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; |
| 630 // Leak the temp file at extension_path. We don't want to add to the disk | 651 // Leak the temp file at extension_path. We don't want to add to the disk |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 842 &extension_file_util::UninstallExtension, | 863 &extension_file_util::UninstallExtension, |
| 843 install_directory_, | 864 install_directory_, |
| 844 extension_id))) | 865 extension_id))) |
| 845 NOTREACHED(); | 866 NOTREACHED(); |
| 846 } | 867 } |
| 847 | 868 |
| 848 GURL launch_web_url_origin(extension->launch_web_url()); | 869 GURL launch_web_url_origin(extension->launch_web_url()); |
| 849 launch_web_url_origin = launch_web_url_origin.GetOrigin(); | 870 launch_web_url_origin = launch_web_url_origin.GetOrigin(); |
| 850 bool is_storage_isolated = extension->is_storage_isolated(); | 871 bool is_storage_isolated = extension->is_storage_isolated(); |
| 851 | 872 |
| 852 if (extension->is_hosted_app() && | 873 if (is_storage_isolated) { |
| 853 !profile_->GetExtensionSpecialStoragePolicy()-> | 874 // TODO(ajwong): At teast abstract this into function. |
| 854 IsStorageProtected(launch_web_url_origin)) { | 875 const GURL& site = Extension::GetBaseURLFromExtensionId(extension_id); |
| 855 extensions::DataDeleter::StartDeleting( | 876 BrowserContext::AsyncObliterateStoragePartition( |
| 856 profile_, extension_id, launch_web_url_origin, is_storage_isolated); | 877 profile_, site, |
| 878 // TODO(ajwong): We must bounce to UI thread and do correct cancelation. | |
|
Charlie Reis
2012/12/05 02:25:40
Not quite sure what this means. Also, long line b
awong
2012/12/08 01:45:23
Resolved it. I hadn't fixed the API to make sure t
| |
| 879 base::Bind(&extensions::ExtensionPrefs::SetNeedsStorageGarbageCollection , | |
| 880 base::Unretained(extension_prefs_), true)); | |
| 881 } else { | |
| 882 if (extension->is_hosted_app() && | |
| 883 !profile_->GetExtensionSpecialStoragePolicy()-> | |
| 884 IsStorageProtected(launch_web_url_origin)) { | |
| 885 extensions::DataDeleter::StartDeleting( | |
| 886 profile_, extension_id, launch_web_url_origin); | |
| 887 } | |
| 888 extensions::DataDeleter::StartDeleting(profile_, extension_id, | |
| 889 extension->url()); | |
| 857 } | 890 } |
| 858 extensions::DataDeleter::StartDeleting( | |
| 859 profile_, extension_id, extension->url(), is_storage_isolated); | |
| 860 | 891 |
| 861 UntrackTerminatedExtension(extension_id); | 892 UntrackTerminatedExtension(extension_id); |
| 862 | 893 |
| 863 // Notify interested parties that we've uninstalled this extension. | 894 // Notify interested parties that we've uninstalled this extension. |
| 864 content::NotificationService::current()->Notify( | 895 content::NotificationService::current()->Notify( |
| 865 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, | 896 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, |
| 866 content::Source<Profile>(profile_), | 897 content::Source<Profile>(profile_), |
| 867 content::Details<const Extension>(extension)); | 898 content::Details<const Extension>(extension)); |
| 868 | 899 |
| 869 if (app_sync_bundle_.HasExtensionId(extension_id) && | 900 if (app_sync_bundle_.HasExtensionId(extension_id) && |
| (...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2272 child_process_logging::SetActiveExtensions(extension_ids); | 2303 child_process_logging::SetActiveExtensions(extension_ids); |
| 2273 } | 2304 } |
| 2274 | 2305 |
| 2275 void ExtensionService::OnExtensionInstalled( | 2306 void ExtensionService::OnExtensionInstalled( |
| 2276 const Extension* extension, | 2307 const Extension* extension, |
| 2277 const syncer::StringOrdinal& page_ordinal, | 2308 const syncer::StringOrdinal& page_ordinal, |
| 2278 bool has_requirement_errors, | 2309 bool has_requirement_errors, |
| 2279 bool wait_for_idle) { | 2310 bool wait_for_idle) { |
| 2280 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2311 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2281 | 2312 |
| 2313 // If installs are delayed, then disable. | |
|
Charlie Reis
2012/12/05 02:25:40
I guess I'm a bit confused by the names here. "On
awong
2012/12/08 01:45:23
Yeah, it confused me too. OnExtensionInstalled()
| |
| 2314 if (delay_all_installs()) { | |
| 2315 pending_extension_installs_.push_back( | |
|
Matt Perry
2012/12/05 19:55:33
Can you explain why reusing the FinishDelayedInsta
awong
2012/12/05 21:01:57
I probably misunderstood the code. What I saw was
Matt Perry
2012/12/05 21:22:08
I think the main question is, exactly what do you
awong
2012/12/08 01:45:23
I've redone this a bit. Let me know what you think
| |
| 2316 PendingInstall(extension, page_ordinal, has_requirement_errors, | |
| 2317 wait_for_idle)); | |
| 2318 return; | |
| 2319 } | |
| 2320 | |
| 2282 const std::string& id = extension->id(); | 2321 const std::string& id = extension->id(); |
| 2283 bool initial_enable = ShouldEnableOnInstall(extension); | 2322 bool initial_enable = ShouldEnableOnInstall(extension); |
| 2284 const extensions::PendingExtensionInfo* pending_extension_info = NULL; | 2323 const extensions::PendingExtensionInfo* pending_extension_info = NULL; |
| 2285 if ((pending_extension_info = pending_extension_manager()->GetById(id))) { | 2324 if ((pending_extension_info = pending_extension_manager()->GetById(id))) { |
| 2286 if (!pending_extension_info->ShouldAllowInstall(*extension)) { | 2325 if (!pending_extension_info->ShouldAllowInstall(*extension)) { |
| 2287 pending_extension_manager()->Remove(id); | 2326 pending_extension_manager()->Remove(id); |
| 2288 | 2327 |
| 2289 LOG(WARNING) << "ShouldAllowInstall() returned false for " | 2328 LOG(WARNING) << "ShouldAllowInstall() returned false for " |
| 2290 << id << " of type " << extension->GetType() | 2329 << id << " of type " << extension->GetType() |
| 2291 << " and update URL " << extension->update_url().spec() | 2330 << " and update URL " << extension->update_url().spec() |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2975 // Delay installation if the extension listens for the onUpdateAvailable | 3014 // Delay installation if the extension listens for the onUpdateAvailable |
| 2976 // event. | 3015 // event. |
| 2977 return system_->event_router()->ExtensionHasEventListener( | 3016 return system_->event_router()->ExtensionHasEventListener( |
| 2978 extension_id, kOnUpdateAvailableEvent); | 3017 extension_id, kOnUpdateAvailableEvent); |
| 2979 } else { | 3018 } else { |
| 2980 // Delay installation if the extension is not idle. | 3019 // Delay installation if the extension is not idle. |
| 2981 return !IsExtensionIdle(extension_id); | 3020 return !IsExtensionIdle(extension_id); |
| 2982 } | 3021 } |
| 2983 } | 3022 } |
| 2984 | 3023 |
| 3024 void ExtensionService::GarbageCollectIsolatedStorage() { | |
| 3025 base::hash_set<FilePath> active_paths; | |
| 3026 for (ExtensionSet::const_iterator it = extensions_.begin(); | |
| 3027 it != extensions_.end(); ++it) { | |
| 3028 if ((*it)->is_storage_isolated()) { | |
| 3029 // TODO(ajwong): This should be passed through effective url or something. | |
| 3030 active_paths.insert( | |
| 3031 BrowserContext::GetStoragePartitionForSite( | |
| 3032 profile_, | |
| 3033 Extension::GetBaseURLFromExtensionId((*it)->id()))->GetPath()); | |
| 3034 } | |
| 3035 } | |
| 3036 | |
| 3037 DCHECK(!delay_all_installs()); | |
| 3038 set_delay_all_installs(true); | |
| 3039 BrowserContext::GarbageCollectStoragePartitions( | |
| 3040 profile_, &active_paths, | |
| 3041 base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished, | |
| 3042 AsWeakPtr())); | |
| 3043 } | |
| 3044 | |
| 3045 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { | |
| 3046 set_delay_all_installs(false); | |
| 3047 for (std::vector<PendingInstall>::const_iterator it = | |
| 3048 pending_extension_installs_.begin(); | |
| 3049 it != pending_extension_installs_.end(); | |
| 3050 ++it) { | |
| 3051 OnExtensionInstalled(it->extension, it->page_ordinal, | |
| 3052 it->has_requirement_errors, it->wait_for_idle); | |
| 3053 } | |
| 3054 pending_extension_installs_.clear(); | |
| 3055 } | |
| 3056 | |
| 2985 void ExtensionService::OnBlacklistUpdated() { | 3057 void ExtensionService::OnBlacklistUpdated() { |
| 2986 CheckManagementPolicy(); | 3058 CheckManagementPolicy(); |
| 2987 } | 3059 } |
| OLD | NEW |