Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(874)

Side by Side Diff: chrome/browser/extensions/extension_service.cc

Issue 695133005: Temporarily disable extensions and sync while a profile is locked - Profiles Approach (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix unit test. Don't lock policy-forced extensions. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698