Chromium Code Reviews| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" | 73 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" |
| 74 #include "chrome/browser/ui/webui/theme_source.h" | 74 #include "chrome/browser/ui/webui/theme_source.h" |
| 75 #include "chrome/common/child_process_logging.h" | 75 #include "chrome/common/child_process_logging.h" |
| 76 #include "chrome/common/chrome_notification_types.h" | 76 #include "chrome/common/chrome_notification_types.h" |
| 77 #include "chrome/common/chrome_paths.h" | 77 #include "chrome/common/chrome_paths.h" |
| 78 #include "chrome/common/chrome_switches.h" | 78 #include "chrome/common/chrome_switches.h" |
| 79 #include "chrome/common/chrome_version_info.h" | 79 #include "chrome/common/chrome_version_info.h" |
| 80 #include "chrome/common/extensions/api/plugins/plugins_handler.h" | 80 #include "chrome/common/extensions/api/plugins/plugins_handler.h" |
| 81 #include "chrome/common/extensions/background_info.h" | 81 #include "chrome/common/extensions/background_info.h" |
| 82 #include "chrome/common/extensions/extension.h" | 82 #include "chrome/common/extensions/extension.h" |
| 83 #include "chrome/common/extensions/extension_constants.h" | |
| 83 #include "chrome/common/extensions/extension_file_util.h" | 84 #include "chrome/common/extensions/extension_file_util.h" |
| 84 #include "chrome/common/extensions/extension_manifest_constants.h" | 85 #include "chrome/common/extensions/extension_manifest_constants.h" |
| 85 #include "chrome/common/extensions/extension_messages.h" | 86 #include "chrome/common/extensions/extension_messages.h" |
| 86 #include "chrome/common/extensions/feature_switch.h" | 87 #include "chrome/common/extensions/feature_switch.h" |
| 87 #include "chrome/common/extensions/features/feature.h" | 88 #include "chrome/common/extensions/features/feature.h" |
| 88 #include "chrome/common/extensions/incognito_handler.h" | 89 #include "chrome/common/extensions/incognito_handler.h" |
| 89 #include "chrome/common/extensions/manifest.h" | 90 #include "chrome/common/extensions/manifest.h" |
| 90 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" | 91 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" |
| 92 #include "chrome/common/extensions/manifest_handlers/shared_module_info.h" | |
| 91 #include "chrome/common/extensions/manifest_url_handler.h" | 93 #include "chrome/common/extensions/manifest_url_handler.h" |
| 92 #include "chrome/common/pref_names.h" | 94 #include "chrome/common/pref_names.h" |
| 93 #include "chrome/common/startup_metric_utils.h" | 95 #include "chrome/common/startup_metric_utils.h" |
| 94 #include "chrome/common/url_constants.h" | 96 #include "chrome/common/url_constants.h" |
| 95 #include "content/public/browser/browser_thread.h" | 97 #include "content/public/browser/browser_thread.h" |
| 96 #include "content/public/browser/devtools_agent_host.h" | 98 #include "content/public/browser/devtools_agent_host.h" |
| 97 #include "content/public/browser/notification_service.h" | 99 #include "content/public/browser/notification_service.h" |
| 98 #include "content/public/browser/notification_types.h" | 100 #include "content/public/browser/notification_types.h" |
| 99 #include "content/public/browser/plugin_service.h" | 101 #include "content/public/browser/plugin_service.h" |
| 100 #include "content/public/browser/render_process_host.h" | 102 #include "content/public/browser/render_process_host.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 123 using content::PluginService; | 125 using content::PluginService; |
| 124 using extensions::CrxInstaller; | 126 using extensions::CrxInstaller; |
| 125 using extensions::Extension; | 127 using extensions::Extension; |
| 126 using extensions::ExtensionIdSet; | 128 using extensions::ExtensionIdSet; |
| 127 using extensions::ExtensionInfo; | 129 using extensions::ExtensionInfo; |
| 128 using extensions::FeatureSwitch; | 130 using extensions::FeatureSwitch; |
| 129 using extensions::Manifest; | 131 using extensions::Manifest; |
| 130 using extensions::PermissionMessage; | 132 using extensions::PermissionMessage; |
| 131 using extensions::PermissionMessages; | 133 using extensions::PermissionMessages; |
| 132 using extensions::PermissionSet; | 134 using extensions::PermissionSet; |
| 135 using extensions::SharedModuleInfo; | |
| 133 using extensions::UnloadedExtensionInfo; | 136 using extensions::UnloadedExtensionInfo; |
| 134 | 137 |
| 135 namespace errors = extension_manifest_errors; | 138 namespace errors = extension_manifest_errors; |
| 136 | 139 |
| 137 namespace { | 140 namespace { |
| 138 | 141 |
| 139 // Histogram values for logging events related to externally installed | 142 // Histogram values for logging events related to externally installed |
| 140 // extensions. | 143 // extensions. |
| 141 enum ExternalExtensionEvent { | 144 enum ExternalExtensionEvent { |
| 142 EXTERNAL_EXTENSION_INSTALLED = 0, | 145 EXTERNAL_EXTENSION_INSTALLED = 0, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 158 const char* kNaClPluginMimeType = "application/x-nacl"; | 161 const char* kNaClPluginMimeType = "application/x-nacl"; |
| 159 | 162 |
| 160 static bool IsSyncableExtension(const Extension& extension) { | 163 static bool IsSyncableExtension(const Extension& extension) { |
| 161 return extension.GetSyncType() == Extension::SYNC_TYPE_EXTENSION; | 164 return extension.GetSyncType() == Extension::SYNC_TYPE_EXTENSION; |
| 162 } | 165 } |
| 163 | 166 |
| 164 static bool IsSyncableApp(const Extension& extension) { | 167 static bool IsSyncableApp(const Extension& extension) { |
| 165 return extension.GetSyncType() == Extension::SYNC_TYPE_APP; | 168 return extension.GetSyncType() == Extension::SYNC_TYPE_APP; |
| 166 } | 169 } |
| 167 | 170 |
| 171 static bool IsSharedModule(const Extension& extension) { | |
| 172 return SharedModuleInfo::IsSharedModule(&extension); | |
| 173 } | |
| 174 | |
| 168 } // namespace | 175 } // namespace |
| 169 | 176 |
| 170 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData() | 177 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData() |
| 171 : background_page_ready(false), | 178 : background_page_ready(false), |
| 172 being_upgraded(false), | 179 being_upgraded(false), |
| 173 has_used_webrequest(false) { | 180 has_used_webrequest(false) { |
| 174 } | 181 } |
| 175 | 182 |
| 176 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { | 183 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { |
| 177 } | 184 } |
| (...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 865 sync_change.sync_data().GetDataType() == syncer::APPS) { | 872 sync_change.sync_data().GetDataType() == syncer::APPS) { |
| 866 app_sync_bundle_.ProcessDeletion(extension_id, sync_change); | 873 app_sync_bundle_.ProcessDeletion(extension_id, sync_change); |
| 867 } else if (extension_sync_bundle_.HasExtensionId(extension_id) && | 874 } else if (extension_sync_bundle_.HasExtensionId(extension_id) && |
| 868 sync_change.sync_data().GetDataType() == syncer::EXTENSIONS) { | 875 sync_change.sync_data().GetDataType() == syncer::EXTENSIONS) { |
| 869 extension_sync_bundle_.ProcessDeletion(extension_id, sync_change); | 876 extension_sync_bundle_.ProcessDeletion(extension_id, sync_change); |
| 870 } | 877 } |
| 871 | 878 |
| 872 delayed_updates_for_idle_.Remove(extension_id); | 879 delayed_updates_for_idle_.Remove(extension_id); |
| 873 delayed_installs_.Remove(extension_id); | 880 delayed_installs_.Remove(extension_id); |
| 874 | 881 |
| 882 PruneSharedModulesOnUninstall(extension); | |
| 883 | |
| 875 // Track the uninstallation. | 884 // Track the uninstallation. |
| 876 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); | 885 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); |
| 877 | 886 |
| 878 return true; | 887 return true; |
| 879 } | 888 } |
| 880 | 889 |
| 881 bool ExtensionService::IsExtensionEnabled( | 890 bool ExtensionService::IsExtensionEnabled( |
| 882 const std::string& extension_id) const { | 891 const std::string& extension_id) const { |
| 883 if (extensions_.Contains(extension_id) || | 892 if (extensions_.Contains(extension_id) || |
| 884 terminated_extensions_.Contains(extension_id)) { | 893 terminated_extensions_.Contains(extension_id)) { |
| (...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2021 content::NotificationService::NoDetails()); | 2030 content::NotificationService::NoDetails()); |
| 2022 } | 2031 } |
| 2023 | 2032 |
| 2024 void ExtensionService::OnLoadedInstalledExtensions() { | 2033 void ExtensionService::OnLoadedInstalledExtensions() { |
| 2025 if (updater_) | 2034 if (updater_) |
| 2026 updater_->Start(); | 2035 updater_->Start(); |
| 2027 | 2036 |
| 2028 OnBlacklistUpdated(); | 2037 OnBlacklistUpdated(); |
| 2029 | 2038 |
| 2030 SetReadyAndNotifyListeners(); | 2039 SetReadyAndNotifyListeners(); |
| 2040 | |
| 2041 CheckImportsOnAllExtensions(); | |
| 2031 } | 2042 } |
| 2032 | 2043 |
| 2033 void ExtensionService::AddExtension(const Extension* extension) { | 2044 void ExtensionService::AddExtension(const Extension* extension) { |
| 2034 // TODO(jstritar): We may be able to get rid of this branch by overriding the | 2045 // TODO(jstritar): We may be able to get rid of this branch by overriding the |
| 2035 // default extension state to DISABLED when the --disable-extensions flag | 2046 // default extension state to DISABLED when the --disable-extensions flag |
| 2036 // is set (http://crbug.com/29067). | 2047 // is set (http://crbug.com/29067). |
| 2037 if (!extensions_enabled() && | 2048 if (!extensions_enabled() && |
| 2038 !extension->is_theme() && | 2049 !extension->is_theme() && |
| 2039 extension->location() != Manifest::COMPONENT && | 2050 extension->location() != Manifest::COMPONENT && |
| 2040 !Manifest::IsExternalLocation(extension->location())) { | 2051 !Manifest::IsExternalLocation(extension->location())) { |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2270 extension_ids.insert(extension->id()); | 2281 extension_ids.insert(extension->id()); |
| 2271 } | 2282 } |
| 2272 | 2283 |
| 2273 child_process_logging::SetActiveExtensions(extension_ids); | 2284 child_process_logging::SetActiveExtensions(extension_ids); |
| 2274 } | 2285 } |
| 2275 | 2286 |
| 2276 void ExtensionService::ScheduleLaunchOnLoad(const std::string& extension_id) { | 2287 void ExtensionService::ScheduleLaunchOnLoad(const std::string& extension_id) { |
| 2277 on_load_events_[extension_id] = EVENT_LAUNCHED; | 2288 on_load_events_[extension_id] = EVENT_LAUNCHED; |
| 2278 } | 2289 } |
| 2279 | 2290 |
| 2291 bool ExtensionService::CheckImports(const Extension* extension) { | |
| 2292 bool import_failed = false; | |
| 2293 if (SharedModuleInfo::ImportsModules(extension)) { | |
| 2294 const std::vector<SharedModuleInfo::ImportInfo>& imports = | |
| 2295 SharedModuleInfo::GetImports(extension); | |
| 2296 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i; | |
| 2297 for (i = imports.begin(); i != imports.end(); ++i) { | |
| 2298 Version version_required(i->minimum_version); | |
| 2299 const Extension* imported_module = | |
| 2300 GetExtensionById(i->extension_id, true); | |
| 2301 if (!imported_module || | |
| 2302 (version_required.IsValid() && | |
| 2303 imported_module->version()->CompareTo(version_required) < 0)) { | |
| 2304 import_failed = true; | |
| 2305 if (extension->from_webstore()) { | |
| 2306 if (pending_extension_manager()->AddFromExtensionImport( | |
|
asargent_no_longer_on_chrome
2013/05/17 17:13:49
in the implementation of PendingExtensionManager::
| |
| 2307 i->extension_id, | |
| 2308 extension_urls::GetWebstoreUpdateUrl(), | |
| 2309 IsSharedModule)) { | |
| 2310 CheckForUpdatesSoon(); | |
| 2311 } | |
| 2312 } | |
| 2313 } | |
| 2314 if (imported_module && | |
| 2315 !SharedModuleInfo::IsSharedModule(imported_module)) { | |
| 2316 import_failed = true; | |
| 2317 } | |
| 2318 } | |
| 2319 } | |
| 2320 const std::string& id = extension->id(); | |
| 2321 if (import_failed) { | |
| 2322 extension_prefs_->AddDisableReason( | |
| 2323 id, Extension::DISABLE_MISSING_IMPORT); | |
| 2324 } else if (extension_prefs_->GetDisableReasons(id) == | |
| 2325 Extension::DISABLE_MISSING_IMPORT) { | |
| 2326 EnableExtension(id); | |
| 2327 } | |
| 2328 return !import_failed; | |
| 2329 } | |
| 2330 | |
| 2331 void ExtensionService::CheckImportsOnAllExtensions() { | |
| 2332 std::vector<const Extension*> extensions_to_check; | |
| 2333 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); | |
| 2334 iter != disabled_extensions_.end(); ++iter) { | |
| 2335 extensions_to_check.push_back(*iter); | |
| 2336 } | |
| 2337 for (ExtensionSet::const_iterator iter = extensions_.begin(); | |
| 2338 iter != extensions_.end(); ++iter) { | |
| 2339 extensions_to_check.push_back(*iter); | |
| 2340 } | |
| 2341 std::vector<const Extension*>::const_iterator iter; | |
| 2342 for (iter = extensions_to_check.begin(); | |
| 2343 iter != extensions_to_check.end(); | |
| 2344 ++iter) { | |
| 2345 CheckImports(*iter); | |
| 2346 } | |
| 2347 } | |
| 2348 | |
| 2349 void ExtensionService::PruneSharedModulesOnUninstall( | |
| 2350 const Extension* extension) { | |
| 2351 if (SharedModuleInfo::ImportsModules(extension)) { | |
| 2352 const std::vector<SharedModuleInfo::ImportInfo>& imports = | |
| 2353 SharedModuleInfo::GetImports(extension); | |
| 2354 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i; | |
| 2355 for (i = imports.begin(); i != imports.end(); ++i) { | |
| 2356 const Extension* imported_module = | |
| 2357 GetExtensionById(i->extension_id, true); | |
| 2358 if (!imported_module) | |
| 2359 continue; | |
| 2360 if (SharedModuleInfo::IsSharedModule(imported_module)) { | |
| 2361 bool is_referenced = false; | |
| 2362 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); | |
| 2363 iter != disabled_extensions_.end(); ++iter) { | |
| 2364 if (SharedModuleInfo::ImportsExtensionById(*iter, i->extension_id)) { | |
| 2365 is_referenced = true; | |
| 2366 break; | |
| 2367 } | |
| 2368 } | |
| 2369 if (!is_referenced) { | |
| 2370 for (ExtensionSet::const_iterator iter = extensions_.begin(); | |
| 2371 iter != extensions_.end(); ++iter) { | |
| 2372 if (SharedModuleInfo::ImportsExtensionById(*iter, | |
| 2373 i->extension_id)) { | |
| 2374 is_referenced = true; | |
| 2375 break; | |
| 2376 } | |
| 2377 } | |
| 2378 } | |
| 2379 if (!is_referenced) { | |
| 2380 UninstallExtension(i->extension_id, false, NULL); | |
| 2381 } | |
| 2382 } | |
| 2383 } | |
| 2384 } | |
| 2385 } | |
| 2386 | |
| 2387 | |
| 2280 void ExtensionService::OnExtensionInstalled( | 2388 void ExtensionService::OnExtensionInstalled( |
| 2281 const Extension* extension, | 2389 const Extension* extension, |
| 2282 const syncer::StringOrdinal& page_ordinal, | 2390 const syncer::StringOrdinal& page_ordinal, |
| 2283 bool has_requirement_errors, | 2391 bool has_requirement_errors, |
| 2284 bool wait_for_idle) { | 2392 bool wait_for_idle) { |
| 2285 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2393 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2286 | 2394 |
| 2287 const std::string& id = extension->id(); | 2395 const std::string& id = extension->id(); |
| 2288 bool initial_enable = ShouldEnableOnInstall(extension); | 2396 bool initial_enable = ShouldEnableOnInstall(extension); |
| 2289 const extensions::PendingExtensionInfo* pending_extension_info = NULL; | 2397 const extensions::PendingExtensionInfo* pending_extension_info = NULL; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2330 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); | 2438 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); |
| 2331 // If the extension was disabled because of unsupported requirements but | 2439 // If the extension was disabled because of unsupported requirements but |
| 2332 // now supports all requirements after an update and there are not other | 2440 // now supports all requirements after an update and there are not other |
| 2333 // disable reasons, enable it. | 2441 // disable reasons, enable it. |
| 2334 } else if (extension_prefs_->GetDisableReasons(id) == | 2442 } else if (extension_prefs_->GetDisableReasons(id) == |
| 2335 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { | 2443 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { |
| 2336 initial_enable = true; | 2444 initial_enable = true; |
| 2337 extension_prefs_->ClearDisableReasons(id); | 2445 extension_prefs_->ClearDisableReasons(id); |
| 2338 } | 2446 } |
| 2339 | 2447 |
| 2448 if (!CheckImports(extension)) { | |
| 2449 initial_enable = false; | |
| 2450 } | |
| 2451 | |
| 2340 if (!GetInstalledExtension(extension->id())) { | 2452 if (!GetInstalledExtension(extension->id())) { |
| 2341 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", | 2453 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", |
| 2342 extension->GetType(), 100); | 2454 extension->GetType(), 100); |
| 2343 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", | 2455 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", |
| 2344 extension->location(), Manifest::NUM_LOCATIONS); | 2456 extension->location(), Manifest::NUM_LOCATIONS); |
| 2345 RecordPermissionMessagesHistogram( | 2457 RecordPermissionMessagesHistogram( |
| 2346 extension, "Extensions.Permissions_Install"); | 2458 extension, "Extensions.Permissions_Install"); |
| 2347 } else { | 2459 } else { |
| 2348 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", | 2460 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", |
| 2349 extension->GetType(), 100); | 2461 extension->GetType(), 100); |
| 2350 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", | 2462 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", |
| 2351 extension->location(), Manifest::NUM_LOCATIONS); | 2463 extension->location(), Manifest::NUM_LOCATIONS); |
| 2352 } | 2464 } |
| 2353 | 2465 |
| 2354 // Certain extension locations are specific enough that we can | 2466 // Certain extension locations are specific enough that we can |
| 2355 // auto-acknowledge any extension that came from one of them. | 2467 // auto-acknowledge any extension that came from one of them. |
| 2356 if (extension->location() == Manifest::EXTERNAL_POLICY_DOWNLOAD) | 2468 if (extension->location() == Manifest::EXTERNAL_POLICY_DOWNLOAD) |
| 2357 AcknowledgeExternalExtension(extension->id()); | 2469 AcknowledgeExternalExtension(extension->id()); |
| 2358 const Extension::State initial_state = | 2470 const Extension::State initial_state = |
| 2359 initial_enable ? Extension::ENABLED : Extension::DISABLED; | 2471 initial_enable ? Extension::ENABLED : Extension::DISABLED; |
| 2360 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) { | 2472 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) { |
|
Matt Perry
2013/05/16 19:17:55
We have this concept of delaying an extension upda
asargent_no_longer_on_chrome
2013/05/17 17:13:49
I endorse Matt's suggestion here.
| |
| 2361 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, | 2473 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, |
| 2362 page_ordinal); | 2474 page_ordinal); |
| 2363 | 2475 |
| 2364 // Transfer ownership of |extension|. | 2476 // Transfer ownership of |extension|. |
| 2365 delayed_updates_for_idle_.Insert(extension); | 2477 delayed_updates_for_idle_.Insert(extension); |
| 2366 | 2478 |
| 2367 // Notify extension of available update. | 2479 // Notify extension of available update. |
| 2368 extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent( | 2480 extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent( |
| 2369 profile_, id, extension->manifest()->value()); | 2481 profile_, id, extension->manifest()->value()); |
| 2370 | 2482 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2457 | 2569 |
| 2458 // If this is a new external extension that was disabled, alert the user | 2570 // If this is a new external extension that was disabled, alert the user |
| 2459 // so he can reenable it. We do this last so that it has already been | 2571 // so he can reenable it. We do this last so that it has already been |
| 2460 // added to our list of extensions. | 2572 // added to our list of extensions. |
| 2461 if (unacknowledged_external) { | 2573 if (unacknowledged_external) { |
| 2462 UpdateExternalExtensionAlert(); | 2574 UpdateExternalExtensionAlert(); |
| 2463 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", | 2575 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", |
| 2464 EXTERNAL_EXTENSION_INSTALLED, | 2576 EXTERNAL_EXTENSION_INSTALLED, |
| 2465 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); | 2577 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); |
| 2466 } | 2578 } |
| 2579 | |
| 2580 // Check extensions that may be disabled only because this shared module was | |
| 2581 // not available. | |
| 2582 if (SharedModuleInfo::IsSharedModule(extension)) { | |
| 2583 // Build a list of extensions to check because they can't be checked | |
| 2584 // within the loop iterating over disabled_extensions_ because contents | |
| 2585 // of that set may change as we CheckImports. | |
| 2586 std::vector<const Extension*> extensions_to_check; | |
| 2587 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); | |
| 2588 iter != disabled_extensions_.end(); ++iter) { | |
| 2589 if (SharedModuleInfo::ImportsExtensionById((*iter), extension->id())) { | |
| 2590 extensions_to_check.push_back(*iter); | |
| 2591 } | |
| 2592 } | |
| 2593 std::vector<const Extension*>::const_iterator iter; | |
| 2594 for (iter = extensions_to_check.begin(); | |
| 2595 iter != extensions_to_check.end(); | |
| 2596 ++iter) { | |
| 2597 CheckImports(*iter); | |
| 2598 } | |
| 2599 } | |
| 2467 } | 2600 } |
| 2468 | 2601 |
| 2469 const Extension* ExtensionService::GetPendingExtensionUpdate( | 2602 const Extension* ExtensionService::GetPendingExtensionUpdate( |
| 2470 const std::string& id) const { | 2603 const std::string& id) const { |
| 2471 return delayed_updates_for_idle_.GetByID(id); | 2604 return delayed_updates_for_idle_.GetByID(id); |
| 2472 } | 2605 } |
| 2473 | 2606 |
| 2474 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { | 2607 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { |
| 2475 if (!terminated_extensions_.Contains(extension->id())) | 2608 if (!terminated_extensions_.Contains(extension->id())) |
| 2476 terminated_extensions_.Insert(make_scoped_refptr(extension)); | 2609 terminated_extensions_.Insert(make_scoped_refptr(extension)); |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3107 } | 3240 } |
| 3108 | 3241 |
| 3109 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { | 3242 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { |
| 3110 update_observers_.AddObserver(observer); | 3243 update_observers_.AddObserver(observer); |
| 3111 } | 3244 } |
| 3112 | 3245 |
| 3113 void ExtensionService::RemoveUpdateObserver( | 3246 void ExtensionService::RemoveUpdateObserver( |
| 3114 extensions::UpdateObserver* observer) { | 3247 extensions::UpdateObserver* observer) { |
| 3115 update_observers_.RemoveObserver(observer); | 3248 update_observers_.RemoveObserver(observer); |
| 3116 } | 3249 } |
| OLD | NEW |