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.
5 #include "chrome/browser/extensions/extension_util.h"
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"
21 namespace extensions {
24 bool IsIncognitoEnabled(const std::string& extension_id,
25 content::BrowserContext* context) {
26 const Extension* extension = ExtensionRegistry::Get(context)->
27 GetExtensionById(extension_id, ExtensionRegistry::ENABLED);
29 if (!extension->can_be_incognito_enabled())
31 // If this is an existing component extension we always allow it to
32 // work in incognito mode.
33 if (extension->location() == Manifest::COMPONENT)
35 if (extension->force_incognito_enabled())
39 return ExtensionPrefs::Get(context)->IsIncognitoEnabled(extension_id);
42 void SetIsIncognitoEnabled(const std::string& extension_id,
43 content::BrowserContext* context,
45 ExtensionService* service =
46 ExtensionSystem::Get(context)->extension_service();
48 const Extension* extension = service->GetInstalledExtension(extension_id);
51 if (!extension->can_be_incognito_enabled())
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));
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()));
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
70 bool old_enabled = extension_prefs->IsIncognitoEnabled(extension_id);
71 if (enabled == old_enabled)
74 extension_prefs->SetIsIncognitoEnabled(extension_id, enabled);
76 bool extension_is_enabled = service->extensions()->Contains(extension_id);
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);
84 // Reloading the extension invalidates the |extension| pointer.
85 extension = service->GetInstalledExtension(id);
87 ExtensionSyncService::Get(service->profile())->
88 SyncExtensionChangeIfNeeded(*extension);
92 bool 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.
98 return IsIncognitoEnabled(extension->id(), context) &&
99 !IncognitoInfo::IsSplitMode(extension);
102 bool CanLoadInIncognito(const Extension* extension,
103 content::BrowserContext* context) {
105 if (extension->is_hosted_app())
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);
113 bool 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);
120 void SetAllowFileAccess(const std::string& extension_id,
121 content::BrowserContext* context,
123 ExtensionService* service =
124 ExtensionSystem::Get(context)->extension_service();
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))
132 service->extension_prefs()->SetAllowFileAccess(extension_id, allow);
134 bool extension_is_enabled = service->extensions()->Contains(extension_id);
135 if (extension_is_enabled)
136 service->ReloadExtension(extension_id);
139 bool IsAppLaunchable(const std::string& extension_id,
140 content::BrowserContext* context) {
141 return !(ExtensionPrefs::Get(context)->GetDisableReasons(extension_id) &
142 Extension::DISABLE_UNSUPPORTED_REQUIREMENT);
145 bool IsAppLaunchableWithoutEnabling(const std::string& extension_id,
146 content::BrowserContext* context) {
147 return ExtensionRegistry::Get(context)->GetExtensionById(
148 extension_id, ExtensionRegistry::ENABLED) != NULL;
151 bool 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);
161 content::SiteInstance* site_instance = process_manager->GetSiteInstanceForURL(
162 Extension::GetBaseURLFromExtensionId(extension_id));
163 if (site_instance && site_instance->HasProcess())
166 return process_manager->GetRenderViewHostsForExtension(extension_id).empty();
169 bool 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();
177 } // namespace extensions