Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_util.cc
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
21 namespace extensions {
22 namespace util {
23
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);
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
42 void 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
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.
97   CHECK(extension);
98   return IsIncognitoEnabled(extension->id(), context) &&
99          !IncognitoInfo::IsSplitMode(extension);
100 }
101
102 bool 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
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);
118 }
119
120 void 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
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);
143 }
144
145 bool IsAppLaunchableWithoutEnabling(const std::string& extension_id,
146                                     content::BrowserContext* context) {
147   return ExtensionRegistry::Get(context)->GetExtensionById(
148       extension_id, ExtensionRegistry::ENABLED) != NULL;
149 }
150
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);
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
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();
174 }
175
176 }  // namespace util
177 }  // namespace extensions