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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 system_->management_policy()->UnregisterProvider( | 369 system_->management_policy()->UnregisterProvider( |
370 shared_module_policy_provider_.get()); | 370 shared_module_policy_provider_.get()); |
371 } | 371 } |
372 | 372 |
373 const Extension* ExtensionService::GetExtensionById( | 373 const Extension* ExtensionService::GetExtensionById( |
374 const std::string& id, bool include_disabled) const { | 374 const std::string& id, bool include_disabled) const { |
375 int include_mask = ExtensionRegistry::ENABLED; | 375 int include_mask = ExtensionRegistry::ENABLED; |
376 if (include_disabled) { | 376 if (include_disabled) { |
377 // Include blacklisted extensions here because there are hundreds of | 377 // Include blacklisted extensions here because there are hundreds of |
378 // callers of this function, and many might assume that this includes those | 378 // callers of this function, and many might assume that this includes those |
379 // that have been disabled due to blacklisting. | 379 // that have been disabled due to blacklisting. |
not at google - send to devlin
2014/11/12 18:23:00
Update comment?
Mike Lerman
2014/11/12 20:58:42
Done.
| |
380 include_mask |= ExtensionRegistry::DISABLED | | 380 include_mask |= ExtensionRegistry::DISABLED | |
381 ExtensionRegistry::BLACKLISTED; | 381 ExtensionRegistry::BLACKLISTED | |
382 ExtensionRegistry::LOCKED; | |
382 } | 383 } |
383 return registry_->GetExtensionById(id, include_mask); | 384 return registry_->GetExtensionById(id, include_mask); |
384 } | 385 } |
385 | 386 |
386 void ExtensionService::Init() { | 387 void ExtensionService::Init() { |
387 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 388 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
388 | 389 |
389 base::Time begin_time = base::Time::Now(); | 390 base::Time begin_time = base::Time::Now(); |
390 | 391 |
391 DCHECK(!is_ready()); // Can't redo init. | 392 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, | 573 const std::string& transient_extension_id, |
573 bool be_noisy) { | 574 bool be_noisy) { |
574 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 575 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
575 | 576 |
576 // If the extension is already reloading, don't reload again. | 577 // If the extension is already reloading, don't reload again. |
577 if (extension_prefs_->GetDisableReasons(transient_extension_id) & | 578 if (extension_prefs_->GetDisableReasons(transient_extension_id) & |
578 Extension::DISABLE_RELOAD) { | 579 Extension::DISABLE_RELOAD) { |
579 return; | 580 return; |
580 } | 581 } |
581 | 582 |
582 // Ignore attempts to reload a blacklisted extension. Sometimes this can | 583 // Ignore attempts to reload a blacklisted or locked extension. Sometimes this |
not at google - send to devlin
2014/11/12 18:22:59
Also update this comment.
Mike Lerman
2014/11/12 20:58:41
Ah, I'd only done half! Thanks. Done.
| |
583 // happen in a convoluted reload sequence triggered by the termination of a | 584 // can happen in a convoluted reload sequence triggered by the termination of |
584 // blacklisted extension and a naive attempt to reload it. For an example see | 585 // a blacklisted extension and a naive attempt to reload it. For an example |
585 // http://crbug.com/373842. | 586 // see http://crbug.com/373842. |
586 if (registry_->blacklisted_extensions().Contains(transient_extension_id)) | 587 if (registry_->blacklisted_extensions().Contains(transient_extension_id) || |
588 registry_->locked_extensions().Contains(transient_extension_id)) { | |
587 return; | 589 return; |
590 } | |
588 | 591 |
589 base::FilePath path; | 592 base::FilePath path; |
590 | 593 |
591 std::string extension_id = transient_extension_id; | 594 std::string extension_id = transient_extension_id; |
592 const Extension* transient_current_extension = | 595 const Extension* transient_current_extension = |
593 GetExtensionById(extension_id, false); | 596 GetExtensionById(extension_id, false); |
594 | 597 |
595 // Disable the extension if it's loaded. It might not be loaded if it crashed. | 598 // Disable the extension if it's loaded. It might not be loaded if it crashed. |
596 if (transient_current_extension) { | 599 if (transient_current_extension) { |
597 // If the extension has an inspector open for its background page, detach | 600 // 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 } | 785 } |
783 | 786 |
784 bool ExtensionService::IsExtensionEnabled( | 787 bool ExtensionService::IsExtensionEnabled( |
785 const std::string& extension_id) const { | 788 const std::string& extension_id) const { |
786 if (registry_->enabled_extensions().Contains(extension_id) || | 789 if (registry_->enabled_extensions().Contains(extension_id) || |
787 registry_->terminated_extensions().Contains(extension_id)) { | 790 registry_->terminated_extensions().Contains(extension_id)) { |
788 return true; | 791 return true; |
789 } | 792 } |
790 | 793 |
791 if (registry_->disabled_extensions().Contains(extension_id) || | 794 if (registry_->disabled_extensions().Contains(extension_id) || |
792 registry_->blacklisted_extensions().Contains(extension_id)) { | 795 registry_->blacklisted_extensions().Contains(extension_id) || |
796 registry_->locked_extensions().Contains(extension_id)) { | |
793 return false; | 797 return false; |
794 } | 798 } |
795 | 799 |
796 // If the extension hasn't been loaded yet, check the prefs for it. Assume | 800 // If the extension hasn't been loaded yet, check the prefs for it. Assume |
797 // enabled unless otherwise noted. | 801 // enabled unless otherwise noted. |
798 return !extension_prefs_->IsExtensionDisabled(extension_id) && | 802 return !extension_prefs_->IsExtensionDisabled(extension_id) && |
799 !extension_prefs_->IsExtensionBlacklisted(extension_id) && | 803 !extension_prefs_->IsExtensionBlacklisted(extension_id) && |
804 !extension_prefs_->IsExtensionLocked(extension_id) && | |
800 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 805 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
801 } | 806 } |
802 | 807 |
803 void ExtensionService::EnableExtension(const std::string& extension_id) { | 808 void ExtensionService::EnableExtension(const std::string& extension_id) { |
804 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 809 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
805 | 810 |
806 if (IsExtensionEnabled(extension_id)) | 811 if (IsExtensionEnabled(extension_id)) |
807 return; | 812 return; |
808 const Extension* extension = | 813 const Extension* extension = |
809 registry_->disabled_extensions().GetByID(extension_id); | 814 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() && | 918 if ((*extension)->was_installed_by_default() && |
914 extension_urls::IsWebstoreUpdateUrl( | 919 extension_urls::IsWebstoreUpdateUrl( |
915 extensions::ManifestURL::GetUpdateURL(extension->get()))) | 920 extensions::ManifestURL::GetUpdateURL(extension->get()))) |
916 continue; | 921 continue; |
917 const std::string& id = (*extension)->id(); | 922 const std::string& id = (*extension)->id(); |
918 if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id)) | 923 if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id)) |
919 DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION); | 924 DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION); |
920 } | 925 } |
921 } | 926 } |
922 | 927 |
928 | |
not at google - send to devlin
2014/11/12 18:23:00
Remove redundant new line.
Mike Lerman
2014/11/12 20:58:42
Done.
| |
929 // Extensions specified by |extension_ids| should become locked. Extensions | |
930 // are no longer considered enabled or disabled. Blacklisted extensions are | |
931 // now considered both blacklisted and locked. | |
932 void ExtensionService::LockAllExtensions() { | |
933 scoped_ptr<ExtensionSet> extensions = | |
934 registry_->GenerateInstalledExtensionsSet(); | |
935 | |
936 ExtensionIdSet to_lock; | |
937 for (ExtensionSet::const_iterator extension = extensions->begin(); | |
not at google - send to devlin
2014/11/12 18:23:00
You could use the new : foreach syntax?
Mike Lerman
2014/11/12 20:58:42
Done.
| |
938 extension != extensions->end(); | |
939 ++extension) { | |
940 const std::string& id = (*extension)->id(); | |
941 if (!registry_->locked_extensions().Contains(id)) | |
942 to_lock.insert(id); | |
943 } | |
944 | |
945 for (ExtensionIdSet::iterator id = to_lock.begin(); | |
946 id != to_lock.end(); ++id) { | |
947 scoped_refptr<const Extension> extension = GetInstalledExtension(*id); | |
not at google - send to devlin
2014/11/12 18:23:00
Unless something is very wrong, this shouldn't be
Mike Lerman
2014/11/12 20:58:42
That saves a lot of code. Thanks!
| |
948 if (!extension.get()) { | |
949 NOTREACHED() << "Extension " << *id << " needs to be " | |
950 << "locked, but it's not installed."; | |
951 continue; | |
952 } | |
953 | |
954 // Don't lock core components. | |
955 if (extension.get()->location() == Manifest::COMPONENT || | |
956 extension.get()->location() == Manifest::EXTERNAL_COMPONENT) { | |
not at google - send to devlin
2014/11/12 18:23:00
Hm, it's surprising that this is the first time we
Mike Lerman
2014/11/12 20:58:42
It seems like this DCHECK in DisableExtension woul
| |
957 continue; | |
958 } | |
959 | |
960 if (system_->management_policy()->MustRemainEnabled(extension.get(), NULL)) | |
961 continue; | |
962 | |
963 // Blacklisted extensions remain in the blacklisted list. | |
not at google - send to devlin
2014/11/12 18:23:00
What about terminated extensions? Those need to go
Mike Lerman
2014/11/12 20:58:42
I had assumed that a terminated extension was A) A
not at google - send to devlin
2014/11/12 23:41:42
You can restart a terminated extension by going to
Mike Lerman
2014/11/13 15:30:04
Acknowledged.
| |
964 if (registry_->enabled_extensions().Contains(*id)) { | |
965 registry_->RemoveEnabled(*id); | |
966 } else if (registry_->disabled_extensions().Contains(*id)) { | |
967 registry_->RemoveDisabled(*id); | |
968 } | |
not at google - send to devlin
2014/11/12 18:23:00
I don't actually think the "if"s here are necessar
Mike Lerman
2014/11/12 20:58:42
Done.
| |
969 registry_->AddLocked(extension.get()); | |
970 extension_prefs_->SetExtensionState(*id, Extension::LOCKED); | |
971 UnloadExtension( | |
972 *id, extensions::UnloadedExtensionInfo::REASON_PROFILE_LOCK); | |
973 } | |
974 } | |
975 | |
976 // All locked extensions should revert to being either enabled or disabled | |
977 // as appropriate. | |
978 void ExtensionService::UnlockAllLockedExtensions() { | |
979 ExtensionIdSet to_unlock = registry_->locked_extensions().GetIDs(); | |
980 | |
981 for (ExtensionIdSet::iterator it = to_unlock.begin(); | |
982 it != to_unlock.end(); ++it) { | |
983 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); | |
984 if (!extension.get()) { | |
985 NOTREACHED() << "Extension " << *it << " needs to be " | |
not at google - send to devlin
2014/11/12 18:23:00
Again; not possible, and this code is perfectly sa
Mike Lerman
2014/11/12 20:58:42
Really? I can't loop directory of registry->locked
not at google - send to devlin
2014/11/12 23:41:42
Oh right, good point, I guess you need to take a c
| |
986 << "unlocked, but it's not installed."; | |
987 continue; | |
988 } | |
989 | |
990 registry_->RemoveLocked(*it); | |
991 if (extension_prefs_->GetDisableReasons(*it)) | |
992 extension_prefs_->SetExtensionState(*it, Extension::DISABLED); | |
993 else | |
994 extension_prefs_->SetExtensionState(*it, Extension::ENABLED); | |
not at google - send to devlin
2014/11/12 18:23:00
Again: terminated extensions.
Mike Lerman
2014/11/12 20:58:42
Done.
| |
995 AddExtension(extension.get()); | |
996 } | |
997 } | |
998 | |
923 void ExtensionService::GrantPermissionsAndEnableExtension( | 999 void ExtensionService::GrantPermissionsAndEnableExtension( |
924 const Extension* extension) { | 1000 const Extension* extension) { |
925 GrantPermissions(extension); | 1001 GrantPermissions(extension); |
926 RecordPermissionMessagesHistogram(extension, | 1002 RecordPermissionMessagesHistogram(extension, |
927 "Extensions.Permissions_ReEnable2"); | 1003 "Extensions.Permissions_ReEnable2"); |
928 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); | 1004 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); |
929 EnableExtension(extension->id()); | 1005 EnableExtension(extension->id()); |
930 } | 1006 } |
931 | 1007 |
932 void ExtensionService::GrantPermissions(const Extension* extension) { | 1008 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. | 1442 // new one. ReloadExtension disables the extension, which is sufficient. |
1367 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE); | 1443 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE); |
1368 } | 1444 } |
1369 | 1445 |
1370 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { | 1446 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { |
1371 // Only prefs is checked for the blacklist. We rely on callers to check the | 1447 // 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 | 1448 // blacklist before calling into here, e.g. CrxInstaller checks before |
1373 // installation then threads through the install and pending install flow | 1449 // installation then threads through the install and pending install flow |
1374 // of this class, and we check when loading installed extensions. | 1450 // of this class, and we check when loading installed extensions. |
1375 registry_->AddBlacklisted(extension); | 1451 registry_->AddBlacklisted(extension); |
1452 } else if (extension_prefs_->IsExtensionLocked(extension->id())) { | |
1453 registry_->AddLocked(extension); | |
1376 } else if (!reloading && | 1454 } else if (!reloading && |
1377 extension_prefs_->IsExtensionDisabled(extension->id())) { | 1455 extension_prefs_->IsExtensionDisabled(extension->id())) { |
1378 registry_->AddDisabled(extension); | 1456 registry_->AddDisabled(extension); |
1379 if (extension_sync_service_) | 1457 if (extension_sync_service_) |
1380 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); | 1458 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); |
1381 content::NotificationService::current()->Notify( | 1459 content::NotificationService::current()->Notify( |
1382 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 1460 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
1383 content::Source<Profile>(profile_), | 1461 content::Source<Profile>(profile_), |
1384 content::Details<const Extension>(extension)); | 1462 content::Details<const Extension>(extension)); |
1385 | 1463 |
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2388 } | 2466 } |
2389 | 2467 |
2390 void ExtensionService::OnProfileDestructionStarted() { | 2468 void ExtensionService::OnProfileDestructionStarted() { |
2391 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); | 2469 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); |
2392 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); | 2470 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); |
2393 it != ids_to_unload.end(); | 2471 it != ids_to_unload.end(); |
2394 ++it) { | 2472 ++it) { |
2395 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); | 2473 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); |
2396 } | 2474 } |
2397 } | 2475 } |
OLD | NEW |