extension_util.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/extensions/extension_util.h" 6 7#include "base/command_line.h" 8#include "chrome/browser/extensions/extension_service.h" 9#include "chrome/browser/extensions/extension_sync_service.h" 10#include "chrome/browser/profiles/profile.h" 11#include "chrome/common/chrome_switches.h" 12#include "chrome/common/extensions/sync_helper.h" 13#include "content/public/browser/site_instance.h" 14#include "extensions/browser/extension_prefs.h" 15#include "extensions/browser/extension_registry.h" 16#include "extensions/browser/extension_system.h" 17#include "extensions/common/extension.h" 18#include "extensions/common/manifest.h" 19#include "extensions/common/manifest_handlers/incognito_info.h" 20 21namespace extensions { 22namespace util { 23 24bool IsIncognitoEnabled(const std::string& extension_id, 25 content::BrowserContext* context) { 26 const Extension* extension = ExtensionRegistry::Get(context)-> 27 GetExtensionById(extension_id, ExtensionRegistry::ENABLED); 28 if (extension) { 29 if (!extension->can_be_incognito_enabled()) 30 return false; 31 // If this is an existing component extension we always allow it to 32 // work in incognito mode. 33 if (extension->location() == Manifest::COMPONENT) 34 return true; 35 if (extension->force_incognito_enabled()) 36 return true; 37 } 38 39 return ExtensionPrefs::Get(context)->IsIncognitoEnabled(extension_id); 40} 41 42void SetIsIncognitoEnabled(const std::string& extension_id, 43 content::BrowserContext* context, 44 bool enabled) { 45 ExtensionService* service = 46 ExtensionSystem::Get(context)->extension_service(); 47 CHECK(service); 48 const Extension* extension = service->GetInstalledExtension(extension_id); 49 50 if (extension) { 51 if (!extension->can_be_incognito_enabled()) 52 return; 53 54 if (extension->location() == Manifest::COMPONENT) { 55 // This shouldn't be called for component extensions unless it is called 56 // by sync, for syncable component extensions. 57 // See http://crbug.com/112290 and associated CLs for the sordid history. 58 DCHECK(sync_helper::IsSyncable(extension)); 59 60 // If we are here, make sure the we aren't trying to change the value. 61 DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, service->profile())); 62 return; 63 } 64 } 65 66 ExtensionPrefs* extension_prefs = service->extension_prefs(); 67 // Broadcast unloaded and loaded events to update browser state. Only bother 68 // if the value changed and the extension is actually enabled, since there is 69 // no UI otherwise. 70 bool old_enabled = extension_prefs->IsIncognitoEnabled(extension_id); 71 if (enabled == old_enabled) 72 return; 73 74 extension_prefs->SetIsIncognitoEnabled(extension_id, enabled); 75 76 bool extension_is_enabled = service->extensions()->Contains(extension_id); 77 78 // When we reload the extension the ID may be invalidated if we've passed it 79 // by const ref everywhere. Make a copy to be safe. 80 std::string id = extension_id; 81 if (extension_is_enabled) 82 service->ReloadExtension(id); 83 84 // Reloading the extension invalidates the |extension| pointer. 85 extension = service->GetInstalledExtension(id); 86 if (extension) { 87 ExtensionSyncService::Get(service->profile())-> 88 SyncExtensionChangeIfNeeded(*extension); 89 } 90} 91 92bool CanCrossIncognito(const Extension* extension, 93 content::BrowserContext* context) { 94 // We allow the extension to see events and data from another profile iff it 95 // uses "spanning" behavior and it has incognito access. "split" mode 96 // extensions only see events for a matching profile. 97 CHECK(extension); 98 return IsIncognitoEnabled(extension->id(), context) && 99 !IncognitoInfo::IsSplitMode(extension); 100} 101 102bool CanLoadInIncognito(const Extension* extension, 103 content::BrowserContext* context) { 104 CHECK(extension); 105 if (extension->is_hosted_app()) 106 return true; 107 // Packaged apps and regular extensions need to be enabled specifically for 108 // incognito (and split mode should be set). 109 return IncognitoInfo::IsSplitMode(extension) && 110 IsIncognitoEnabled(extension->id(), context); 111} 112 113bool AllowFileAccess(const std::string& extension_id, 114 content::BrowserContext* context) { 115 return CommandLine::ForCurrentProcess()->HasSwitch( 116 switches::kDisableExtensionsFileAccessCheck) || 117 ExtensionPrefs::Get(context)->AllowFileAccess(extension_id); 118} 119 120void SetAllowFileAccess(const std::string& extension_id, 121 content::BrowserContext* context, 122 bool allow) { 123 ExtensionService* service = 124 ExtensionSystem::Get(context)->extension_service(); 125 CHECK(service); 126 127 // Reload to update browser state. Only bother if the value changed and the 128 // extension is actually enabled, since there is no UI otherwise. 129 if (allow == AllowFileAccess(extension_id, context)) 130 return; 131 132 service->extension_prefs()->SetAllowFileAccess(extension_id, allow); 133 134 bool extension_is_enabled = service->extensions()->Contains(extension_id); 135 if (extension_is_enabled) 136 service->ReloadExtension(extension_id); 137} 138 139bool IsAppLaunchable(const std::string& extension_id, 140 content::BrowserContext* context) { 141 return !(ExtensionPrefs::Get(context)->GetDisableReasons(extension_id) & 142 Extension::DISABLE_UNSUPPORTED_REQUIREMENT); 143} 144 145bool IsAppLaunchableWithoutEnabling(const std::string& extension_id, 146 content::BrowserContext* context) { 147 return ExtensionRegistry::Get(context)->GetExtensionById( 148 extension_id, ExtensionRegistry::ENABLED) != NULL; 149} 150 151bool IsExtensionIdle(const std::string& extension_id, 152 content::BrowserContext* context) { 153 ProcessManager* process_manager = 154 ExtensionSystem::Get(context)->process_manager(); 155 DCHECK(process_manager); 156 ExtensionHost* host = 157 process_manager->GetBackgroundHostForExtension(extension_id); 158 if (host) 159 return false; 160 161 content::SiteInstance* site_instance = process_manager->GetSiteInstanceForURL( 162 Extension::GetBaseURLFromExtensionId(extension_id)); 163 if (site_instance && site_instance->HasProcess()) 164 return false; 165 166 return process_manager->GetRenderViewHostsForExtension(extension_id).empty(); 167} 168 169bool IsExtensionInstalledPermanently(const std::string& extension_id, 170 content::BrowserContext* context) { 171 const Extension* extension = ExtensionRegistry::Get(context)-> 172 GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); 173 return extension && !extension->is_ephemeral(); 174} 175 176} // namespace util 177} // namespace extensions 178