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 |