extension_util.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 } 36 37 return ExtensionPrefs::Get(context)->IsIncognitoEnabled(extension_id); 38} 39 40void SetIsIncognitoEnabled(const std::string& extension_id, 41 content::BrowserContext* context, 42 bool enabled) { 43 ExtensionService* service = 44 ExtensionSystem::Get(context)->extension_service(); 45 CHECK(service); 46 const Extension* extension = service->GetInstalledExtension(extension_id); 47 48 if (extension) { 49 if (!extension->can_be_incognito_enabled()) 50 return; 51 52 if (extension->location() == Manifest::COMPONENT) { 53 // This shouldn't be called for component extensions unless it is called 54 // by sync, for syncable component extensions. 55 // See http://crbug.com/112290 and associated CLs for the sordid history. 56 DCHECK(sync_helper::IsSyncable(extension)); 57 58 // If we are here, make sure the we aren't trying to change the value. 59 DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, service->profile())); 60 return; 61 } 62 } 63 64 ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(service->profile()); 65 // Broadcast unloaded and loaded events to update browser state. Only bother 66 // if the value changed and the extension is actually enabled, since there is 67 // no UI otherwise. 68 bool old_enabled = extension_prefs->IsIncognitoEnabled(extension_id); 69 if (enabled == old_enabled) 70 return; 71 72 extension_prefs->SetIsIncognitoEnabled(extension_id, enabled); 73 74 bool extension_is_enabled = service->extensions()->Contains(extension_id); 75 76 // When we reload the extension the ID may be invalidated if we've passed it 77 // by const ref everywhere. Make a copy to be safe. 78 std::string id = extension_id; 79 if (extension_is_enabled) 80 service->ReloadExtension(id); 81 82 // Reloading the extension invalidates the |extension| pointer. 83 extension = service->GetInstalledExtension(id); 84 if (extension) { 85 ExtensionSyncService::Get(service->profile())-> 86 SyncExtensionChangeIfNeeded(*extension); 87 } 88} 89 90bool CanCrossIncognito(const Extension* extension, 91 content::BrowserContext* context) { 92 // We allow the extension to see events and data from another profile iff it 93 // uses "spanning" behavior and it has incognito access. "split" mode 94 // extensions only see events for a matching profile. 95 CHECK(extension); 96 return IsIncognitoEnabled(extension->id(), context) && 97 !IncognitoInfo::IsSplitMode(extension); 98} 99 100bool CanLoadInIncognito(const Extension* extension, 101 content::BrowserContext* context) { 102 CHECK(extension); 103 if (extension->is_hosted_app()) 104 return true; 105 // Packaged apps and regular extensions need to be enabled specifically for 106 // incognito (and split mode should be set). 107 return IncognitoInfo::IsSplitMode(extension) && 108 IsIncognitoEnabled(extension->id(), context); 109} 110 111bool AllowFileAccess(const std::string& extension_id, 112 content::BrowserContext* context) { 113 return CommandLine::ForCurrentProcess()->HasSwitch( 114 switches::kDisableExtensionsFileAccessCheck) || 115 ExtensionPrefs::Get(context)->AllowFileAccess(extension_id); 116} 117 118void SetAllowFileAccess(const std::string& extension_id, 119 content::BrowserContext* context, 120 bool allow) { 121 ExtensionService* service = 122 ExtensionSystem::Get(context)->extension_service(); 123 CHECK(service); 124 125 // Reload to update browser state. Only bother if the value changed and the 126 // extension is actually enabled, since there is no UI otherwise. 127 if (allow == AllowFileAccess(extension_id, context)) 128 return; 129 130 ExtensionPrefs::Get(context)->SetAllowFileAccess(extension_id, allow); 131 132 bool extension_is_enabled = service->extensions()->Contains(extension_id); 133 if (extension_is_enabled) 134 service->ReloadExtension(extension_id); 135} 136 137bool IsAppLaunchable(const std::string& extension_id, 138 content::BrowserContext* context) { 139 return !(ExtensionPrefs::Get(context)->GetDisableReasons(extension_id) & 140 Extension::DISABLE_UNSUPPORTED_REQUIREMENT); 141} 142 143bool IsAppLaunchableWithoutEnabling(const std::string& extension_id, 144 content::BrowserContext* context) { 145 return ExtensionRegistry::Get(context)->GetExtensionById( 146 extension_id, ExtensionRegistry::ENABLED) != NULL; 147} 148 149bool IsExtensionIdle(const std::string& extension_id, 150 content::BrowserContext* context) { 151 ProcessManager* process_manager = 152 ExtensionSystem::Get(context)->process_manager(); 153 DCHECK(process_manager); 154 ExtensionHost* host = 155 process_manager->GetBackgroundHostForExtension(extension_id); 156 if (host) 157 return false; 158 159 content::SiteInstance* site_instance = process_manager->GetSiteInstanceForURL( 160 Extension::GetBaseURLFromExtensionId(extension_id)); 161 if (site_instance && site_instance->HasProcess()) 162 return false; 163 164 return process_manager->GetRenderViewHostsForExtension(extension_id).empty(); 165} 166 167bool IsExtensionInstalledPermanently(const std::string& extension_id, 168 content::BrowserContext* context) { 169 const Extension* extension = ExtensionRegistry::Get(context)-> 170 GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); 171 return extension && !extension->is_ephemeral(); 172} 173 174GURL GetSiteForExtensionId(const std::string& extension_id, 175 content::BrowserContext* context) { 176 return content::SiteInstance::GetSiteForURL( 177 context, Extension::GetBaseURLFromExtensionId(extension_id)); 178} 179 180} // namespace util 181} // namespace extensions 182