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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 263 pending_extension_manager_(profile), | 263 pending_extension_manager_(profile), |
| 264 install_directory_(install_directory), | 264 install_directory_(install_directory), |
| 265 extensions_enabled_(extensions_enabled), | 265 extensions_enabled_(extensions_enabled), |
| 266 show_extensions_prompts_(true), | 266 show_extensions_prompts_(true), |
| 267 install_updates_when_idle_(true), | 267 install_updates_when_idle_(true), |
| 268 ready_(ready), | 268 ready_(ready), |
| 269 update_once_all_providers_are_ready_(false), | 269 update_once_all_providers_are_ready_(false), |
| 270 browser_terminating_(false), | 270 browser_terminating_(false), |
| 271 installs_delayed_for_gc_(false), | 271 installs_delayed_for_gc_(false), |
| 272 is_first_run_(false), | 272 is_first_run_(false), |
| 273 block_extensions_(false), | |
| 273 shared_module_service_(new extensions::SharedModuleService(profile_)) { | 274 shared_module_service_(new extensions::SharedModuleService(profile_)) { |
| 274 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 275 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 275 | 276 |
| 276 // Figure out if extension installation should be enabled. | 277 // Figure out if extension installation should be enabled. |
| 277 if (extensions::ExtensionsBrowserClient::Get()->AreExtensionsDisabled( | 278 if (extensions::ExtensionsBrowserClient::Get()->AreExtensionsDisabled( |
| 278 *command_line, profile)) | 279 *command_line, profile)) |
| 279 extensions_enabled_ = false; | 280 extensions_enabled_ = false; |
| 280 | 281 |
| 281 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 282 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
| 282 content::NotificationService::AllBrowserContextsAndSources()); | 283 content::NotificationService::AllBrowserContextsAndSources()); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 ->GetForBrowserContext(profile()) | 368 ->GetForBrowserContext(profile()) |
| 368 ->RemoveObserver(this); | 369 ->RemoveObserver(this); |
| 369 system_->management_policy()->UnregisterProvider( | 370 system_->management_policy()->UnregisterProvider( |
| 370 shared_module_policy_provider_.get()); | 371 shared_module_policy_provider_.get()); |
| 371 } | 372 } |
| 372 | 373 |
| 373 const Extension* ExtensionService::GetExtensionById( | 374 const Extension* ExtensionService::GetExtensionById( |
| 374 const std::string& id, bool include_disabled) const { | 375 const std::string& id, bool include_disabled) const { |
| 375 int include_mask = ExtensionRegistry::ENABLED; | 376 int include_mask = ExtensionRegistry::ENABLED; |
| 376 if (include_disabled) { | 377 if (include_disabled) { |
| 377 // Include blacklisted extensions here because there are hundreds of | 378 // Include blacklisted and blocked extensions here because there are |
| 378 // callers of this function, and many might assume that this includes those | 379 // hundreds of callers of this function, and many might assume that this |
| 379 // that have been disabled due to blacklisting. | 380 // includes those that have been disabled due to blacklisting or blocking. |
| 380 include_mask |= ExtensionRegistry::DISABLED | | 381 include_mask |= ExtensionRegistry::DISABLED | |
| 381 ExtensionRegistry::BLACKLISTED; | 382 ExtensionRegistry::BLACKLISTED | |
| 383 ExtensionRegistry::BLOCKED; | |
| 382 } | 384 } |
| 383 return registry_->GetExtensionById(id, include_mask); | 385 return registry_->GetExtensionById(id, include_mask); |
| 384 } | 386 } |
| 385 | 387 |
| 386 void ExtensionService::Init() { | 388 void ExtensionService::Init() { |
| 387 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 389 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 388 | 390 |
| 389 base::Time begin_time = base::Time::Now(); | 391 base::Time begin_time = base::Time::Now(); |
| 390 | 392 |
| 391 DCHECK(!is_ready()); // Can't redo init. | 393 DCHECK(!is_ready()); // Can't redo init. |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 const std::string& transient_extension_id, | 574 const std::string& transient_extension_id, |
| 573 bool be_noisy) { | 575 bool be_noisy) { |
| 574 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 576 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 575 | 577 |
| 576 // If the extension is already reloading, don't reload again. | 578 // If the extension is already reloading, don't reload again. |
| 577 if (extension_prefs_->GetDisableReasons(transient_extension_id) & | 579 if (extension_prefs_->GetDisableReasons(transient_extension_id) & |
| 578 Extension::DISABLE_RELOAD) { | 580 Extension::DISABLE_RELOAD) { |
| 579 return; | 581 return; |
| 580 } | 582 } |
| 581 | 583 |
| 582 // Ignore attempts to reload a blacklisted extension. Sometimes this can | 584 // Ignore attempts to reload a blacklisted or blocked extension. Sometimes |
| 583 // happen in a convoluted reload sequence triggered by the termination of a | 585 // this can happen in a convoluted reload sequence triggered by the |
| 584 // blacklisted extension and a naive attempt to reload it. For an example see | 586 // termination of a blacklisted or blocked extension and a naive attempt to |
| 585 // http://crbug.com/373842. | 587 // reload it. For an example see http://crbug.com/373842. |
| 586 if (registry_->blacklisted_extensions().Contains(transient_extension_id)) | 588 if (registry_->blacklisted_extensions().Contains(transient_extension_id) || |
| 589 registry_->blocked_extensions().Contains(transient_extension_id)) { | |
| 587 return; | 590 return; |
| 591 } | |
| 588 | 592 |
| 589 base::FilePath path; | 593 base::FilePath path; |
| 590 | 594 |
| 591 std::string extension_id = transient_extension_id; | 595 std::string extension_id = transient_extension_id; |
| 592 const Extension* transient_current_extension = | 596 const Extension* transient_current_extension = |
| 593 GetExtensionById(extension_id, false); | 597 GetExtensionById(extension_id, false); |
| 594 | 598 |
| 595 // Disable the extension if it's loaded. It might not be loaded if it crashed. | 599 // Disable the extension if it's loaded. It might not be loaded if it crashed. |
| 596 if (transient_current_extension) { | 600 if (transient_current_extension) { |
| 597 // If the extension has an inspector open for its background page, detach | 601 // If the extension has an inspector open for its background page, detach |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 } | 786 } |
| 783 | 787 |
| 784 bool ExtensionService::IsExtensionEnabled( | 788 bool ExtensionService::IsExtensionEnabled( |
| 785 const std::string& extension_id) const { | 789 const std::string& extension_id) const { |
| 786 if (registry_->enabled_extensions().Contains(extension_id) || | 790 if (registry_->enabled_extensions().Contains(extension_id) || |
| 787 registry_->terminated_extensions().Contains(extension_id)) { | 791 registry_->terminated_extensions().Contains(extension_id)) { |
| 788 return true; | 792 return true; |
| 789 } | 793 } |
| 790 | 794 |
| 791 if (registry_->disabled_extensions().Contains(extension_id) || | 795 if (registry_->disabled_extensions().Contains(extension_id) || |
| 792 registry_->blacklisted_extensions().Contains(extension_id)) { | 796 registry_->blacklisted_extensions().Contains(extension_id) || |
| 797 registry_->blocked_extensions().Contains(extension_id)) { | |
| 793 return false; | 798 return false; |
| 794 } | 799 } |
| 795 | 800 |
| 796 // If the extension hasn't been loaded yet, check the prefs for it. Assume | 801 // If the extension hasn't been loaded yet, check the prefs for it. Assume |
| 797 // enabled unless otherwise noted. | 802 // enabled unless otherwise noted. |
| 798 return !extension_prefs_->IsExtensionDisabled(extension_id) && | 803 return !extension_prefs_->IsExtensionDisabled(extension_id) && |
| 799 !extension_prefs_->IsExtensionBlacklisted(extension_id) && | 804 !extension_prefs_->IsExtensionBlacklisted(extension_id) && |
| 805 !extension_prefs_->IsExtensionBlocked(extension_id) && | |
| 800 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 806 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
| 801 } | 807 } |
| 802 | 808 |
| 803 void ExtensionService::EnableExtension(const std::string& extension_id) { | 809 void ExtensionService::EnableExtension(const std::string& extension_id) { |
| 804 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 810 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 805 | 811 |
| 806 if (IsExtensionEnabled(extension_id)) | 812 if (IsExtensionEnabled(extension_id)) |
| 807 return; | 813 return; |
| 808 const Extension* extension = | 814 const Extension* extension = |
| 809 registry_->disabled_extensions().GetByID(extension_id); | 815 registry_->disabled_extensions().GetByID(extension_id); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 913 if ((*extension)->was_installed_by_default() && | 919 if ((*extension)->was_installed_by_default() && |
| 914 extension_urls::IsWebstoreUpdateUrl( | 920 extension_urls::IsWebstoreUpdateUrl( |
| 915 extensions::ManifestURL::GetUpdateURL(extension->get()))) | 921 extensions::ManifestURL::GetUpdateURL(extension->get()))) |
| 916 continue; | 922 continue; |
| 917 const std::string& id = (*extension)->id(); | 923 const std::string& id = (*extension)->id(); |
| 918 if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id)) | 924 if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id)) |
| 919 DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION); | 925 DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION); |
| 920 } | 926 } |
| 921 } | 927 } |
| 922 | 928 |
| 929 // Extensions that are not locked, components or forced by policy should be | |
| 930 // locked. Extensions are no longer considered enabled or disabled. Blacklisted | |
| 931 // extensions are now considered both blacklisted and locked. | |
| 932 void ExtensionService::BlockAllExtensions() { | |
|
not at google - send to devlin
2014/11/12 23:41:43
Oh, you might want to check that it's not already
Mike Lerman
2014/11/13 15:30:05
There's no reason this method couldn't be called m
| |
| 933 block_extensions_ = true; | |
| 934 scoped_ptr<ExtensionSet> extensions = | |
| 935 registry_->GenerateInstalledExtensionsSet(); | |
| 936 | |
| 937 ExtensionIdSet to_lock; | |
|
not at google - send to devlin
2014/11/12 23:41:43
You can delete this now.
Mike Lerman
2014/11/13 15:30:05
Bye bye!
| |
| 938 for (const scoped_refptr<const Extension> extension : *extensions.get()) { | |
| 939 const std::string& id = extension.get()->id(); | |
|
not at google - send to devlin
2014/11/12 23:41:43
just extension->id();
Mike Lerman
2014/11/13 15:30:04
Done.
| |
| 940 | |
| 941 if (!CanBlockExtension(extension.get())) | |
| 942 continue; | |
| 943 | |
| 944 // Blacklisted extensions remain in the blacklisted list. | |
| 945 registry_->RemoveEnabled(id); | |
| 946 registry_->RemoveDisabled(id); | |
| 947 registry_->RemoveTerminated(id); | |
| 948 | |
|
not at google - send to devlin
2014/11/12 23:41:43
Come to think of it it's probably also wise/safer
Mike Lerman
2014/11/13 15:30:05
I'm concerned about removing things from the black
not at google - send to devlin
2014/11/13 18:09:47
I'm not suggesting removing it from the blacklist.
Mike Lerman
2014/11/13 21:42:32
Done.
| |
| 949 registry_->AddBlocked(extension.get()); | |
| 950 extension_prefs_->SetExtensionState(id, Extension::BLOCKED); | |
|
not at google - send to devlin
2014/11/12 23:41:43
Actually - why do you need to change prefs at all?
Mike Lerman
2014/11/13 15:30:04
The goal was the keep the ExtensionState sync-ed w
not at google - send to devlin
2014/11/13 18:09:47
I don't think so. For example we keep terminated e
Mike Lerman
2014/11/13 21:42:32
Done.
| |
| 951 UnloadExtension( | |
| 952 id, extensions::UnloadedExtensionInfo::REASON_LOCK_ALL); | |
| 953 } | |
| 954 } | |
| 955 | |
| 956 // All locked extensions should revert to being either enabled or disabled | |
| 957 // as appropriate. | |
| 958 void ExtensionService::UnblockAllBlockedExtensions() { | |
| 959 ExtensionIdSet to_unblock = registry_->blocked_extensions().GetIDs(); | |
|
not at google - send to devlin
2014/11/12 23:41:43
(see previous point about just copying the whole e
Mike Lerman
2014/11/13 15:30:04
Which one?
Is making a copy of the set better tha
not at google - send to devlin
2014/11/13 18:09:47
Maybe they should copy the set as well. Needing 7
Mike Lerman
2014/11/13 21:42:32
Copied as well. Done.
| |
| 960 | |
| 961 block_extensions_ = false; | |
| 962 for (ExtensionIdSet::iterator it = to_unblock.begin(); | |
|
not at google - send to devlin
2014/11/12 23:41:43
(and use : syntax here too)
Mike Lerman
2014/11/13 15:30:04
Done.
| |
| 963 it != to_unblock.end(); ++it) { | |
| 964 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); | |
| 965 if (!extension.get()) { | |
| 966 NOTREACHED() << "Extension " << *it << " needs to be " | |
| 967 << "unblocked, but it's not installed."; | |
| 968 continue; | |
| 969 } | |
| 970 | |
| 971 registry_->RemoveBlocked(*it); | |
| 972 if (extensions_being_terminated_.find(extension->id()) != | |
|
not at google - send to devlin
2014/11/12 23:41:43
Mm, maybe this isn't actually useful. I doubt this
Mike Lerman
2014/11/13 15:30:05
Done.
| |
| 973 extensions_being_terminated_.end()) { | |
| 974 registry_->AddTerminated(extension.get()); | |
| 975 } else { | |
| 976 if (extension_prefs_->GetDisableReasons(*it)) { | |
|
not at google - send to devlin
2014/11/12 23:41:43
GetDisableReasons returns a bitmask, so it's a lit
Mike Lerman
2014/11/13 15:30:04
I agree about using IsExtensionDisabled, if we hav
| |
| 977 extension_prefs_->SetExtensionState(*it, Extension::DISABLED); | |
| 978 } else { | |
| 979 extension_prefs_->SetExtensionState(*it, Extension::ENABLED); | |
| 980 } | |
| 981 AddExtension(extension.get()); | |
| 982 } | |
| 983 } | |
| 984 } | |
| 985 | |
| 923 void ExtensionService::GrantPermissionsAndEnableExtension( | 986 void ExtensionService::GrantPermissionsAndEnableExtension( |
| 924 const Extension* extension) { | 987 const Extension* extension) { |
| 925 GrantPermissions(extension); | 988 GrantPermissions(extension); |
| 926 RecordPermissionMessagesHistogram(extension, | 989 RecordPermissionMessagesHistogram(extension, |
| 927 "Extensions.Permissions_ReEnable2"); | 990 "Extensions.Permissions_ReEnable2"); |
| 928 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); | 991 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); |
| 929 EnableExtension(extension->id()); | 992 EnableExtension(extension->id()); |
| 930 } | 993 } |
| 931 | 994 |
| 932 void ExtensionService::GrantPermissions(const Extension* extension) { | 995 void ExtensionService::GrantPermissions(const Extension* extension) { |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1366 // new one. ReloadExtension disables the extension, which is sufficient. | 1429 // new one. ReloadExtension disables the extension, which is sufficient. |
| 1367 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE); | 1430 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE); |
| 1368 } | 1431 } |
| 1369 | 1432 |
| 1370 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { | 1433 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { |
| 1371 // Only prefs is checked for the blacklist. We rely on callers to check the | 1434 // Only prefs is checked for the blacklist. We rely on callers to check the |
| 1372 // blacklist before calling into here, e.g. CrxInstaller checks before | 1435 // blacklist before calling into here, e.g. CrxInstaller checks before |
| 1373 // installation then threads through the install and pending install flow | 1436 // installation then threads through the install and pending install flow |
| 1374 // of this class, and we check when loading installed extensions. | 1437 // of this class, and we check when loading installed extensions. |
| 1375 registry_->AddBlacklisted(extension); | 1438 registry_->AddBlacklisted(extension); |
| 1439 } else if (extension_prefs_->IsExtensionBlocked(extension->id()) || | |
| 1440 (block_extensions_ && CanBlockExtension(extension))) { | |
| 1441 registry_->AddBlocked(extension); | |
| 1376 } else if (!reloading && | 1442 } else if (!reloading && |
| 1377 extension_prefs_->IsExtensionDisabled(extension->id())) { | 1443 extension_prefs_->IsExtensionDisabled(extension->id())) { |
| 1378 registry_->AddDisabled(extension); | 1444 registry_->AddDisabled(extension); |
| 1379 if (extension_sync_service_) | 1445 if (extension_sync_service_) |
| 1380 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); | 1446 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); |
| 1381 content::NotificationService::current()->Notify( | 1447 content::NotificationService::current()->Notify( |
| 1382 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 1448 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
| 1383 content::Source<Profile>(profile_), | 1449 content::Source<Profile>(profile_), |
| 1384 content::Details<const Extension>(extension)); | 1450 content::Details<const Extension>(extension)); |
| 1385 | 1451 |
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2168 if (extension->GetType() != Manifest::TYPE_HOSTED_APP && | 2234 if (extension->GetType() != Manifest::TYPE_HOSTED_APP && |
| 2169 Manifest::IsExternalLocation(extension->location()) && | 2235 Manifest::IsExternalLocation(extension->location()) && |
| 2170 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) { | 2236 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) { |
| 2171 return false; | 2237 return false; |
| 2172 } | 2238 } |
| 2173 } | 2239 } |
| 2174 | 2240 |
| 2175 return true; | 2241 return true; |
| 2176 } | 2242 } |
| 2177 | 2243 |
| 2244 // Helper method to determine if an extension can be blocked. | |
| 2245 bool ExtensionService::CanBlockExtension(const Extension* extension) { | |
| 2246 return (extension->location() != Manifest::COMPONENT && | |
|
not at google - send to devlin
2014/11/12 23:41:43
Outer parens are unnecessary.
Mike Lerman
2014/11/13 15:30:04
Done.
| |
| 2247 extension->location() != Manifest::EXTERNAL_COMPONENT && | |
| 2248 !system_->management_policy()->MustRemainEnabled(extension, NULL)); | |
| 2249 } | |
| 2250 | |
| 2178 bool ExtensionService::ShouldDelayExtensionUpdate( | 2251 bool ExtensionService::ShouldDelayExtensionUpdate( |
| 2179 const std::string& extension_id, | 2252 const std::string& extension_id, |
| 2180 bool install_immediately) const { | 2253 bool install_immediately) const { |
| 2181 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; | 2254 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; |
| 2182 | 2255 |
| 2183 // If delayed updates are globally disabled, or just for this extension, | 2256 // If delayed updates are globally disabled, or just for this extension, |
| 2184 // don't delay. | 2257 // don't delay. |
| 2185 if (!install_updates_when_idle_ || install_immediately) | 2258 if (!install_updates_when_idle_ || install_immediately) |
| 2186 return false; | 2259 return false; |
| 2187 | 2260 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2256 case extensions::BLACKLISTED_POTENTIALLY_UNWANTED: | 2329 case extensions::BLACKLISTED_POTENTIALLY_UNWANTED: |
| 2257 greylist.insert(it->first); | 2330 greylist.insert(it->first); |
| 2258 break; | 2331 break; |
| 2259 | 2332 |
| 2260 case extensions::BLACKLISTED_UNKNOWN: | 2333 case extensions::BLACKLISTED_UNKNOWN: |
| 2261 unchanged.insert(it->first); | 2334 unchanged.insert(it->first); |
| 2262 break; | 2335 break; |
| 2263 } | 2336 } |
| 2264 } | 2337 } |
| 2265 | 2338 |
| 2266 UpdateBlockedExtensions(blocked, unchanged); | 2339 UpdateBlockedExtensions(blocked, unchanged); |
|
not at google - send to devlin
2014/11/12 23:41:43
Looks like the "blocked" term is already used, but
Mike Lerman
2014/11/13 15:30:04
Done.
| |
| 2267 UpdateGreylistedExtensions(greylist, unchanged, state_map); | 2340 UpdateGreylistedExtensions(greylist, unchanged, state_map); |
| 2268 | 2341 |
| 2269 error_controller_->ShowErrorIfNeeded(); | 2342 error_controller_->ShowErrorIfNeeded(); |
| 2270 } | 2343 } |
| 2271 | 2344 |
| 2272 namespace { | 2345 namespace { |
| 2273 void Partition(const ExtensionIdSet& before, | 2346 void Partition(const ExtensionIdSet& before, |
| 2274 const ExtensionIdSet& after, | 2347 const ExtensionIdSet& after, |
| 2275 const ExtensionIdSet& unchanged, | 2348 const ExtensionIdSet& unchanged, |
| 2276 ExtensionIdSet* no_longer, | 2349 ExtensionIdSet* no_longer, |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2388 } | 2461 } |
| 2389 | 2462 |
| 2390 void ExtensionService::OnProfileDestructionStarted() { | 2463 void ExtensionService::OnProfileDestructionStarted() { |
| 2391 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); | 2464 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); |
| 2392 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); | 2465 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); |
| 2393 it != ids_to_unload.end(); | 2466 it != ids_to_unload.end(); |
| 2394 ++it) { | 2467 ++it) { |
| 2395 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); | 2468 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); |
| 2396 } | 2469 } |
| 2397 } | 2470 } |
| OLD | NEW |