• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_prefs.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/extension_sync_service.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "chrome/common/extensions/sync_helper.h"
13 #include "extensions/common/extension.h"
14 #include "extensions/common/manifest.h"
15 #include "extensions/common/manifest_handlers/incognito_info.h"
16 
17 using extensions::Extension;
18 using extensions::ExtensionPrefs;
19 
20 namespace extension_util {
21 
IsIncognitoEnabled(const std::string & extension_id,const ExtensionService * service)22 bool IsIncognitoEnabled(const std::string& extension_id,
23                         const ExtensionService* service) {
24   if (!service)
25     return false;
26 
27   const Extension* extension = service->GetInstalledExtension(extension_id);
28   if (extension && !extension->can_be_incognito_enabled())
29     return false;
30   // If this is an existing component extension we always allow it to
31   // work in incognito mode.
32   if (extension && extension->location() == extensions::Manifest::COMPONENT)
33     return true;
34   if (extension && extension->force_incognito_enabled())
35     return true;
36 
37   // Check the prefs.
38   return service->extension_prefs()->IsIncognitoEnabled(extension_id);
39 }
40 
SetIsIncognitoEnabled(const std::string & extension_id,ExtensionService * service,bool enabled)41 void SetIsIncognitoEnabled(const std::string& extension_id,
42                            ExtensionService* service,
43                            bool enabled) {
44   const Extension* extension = service->GetInstalledExtension(extension_id);
45   if (extension && !extension->can_be_incognito_enabled())
46     return;
47   if (extension && extension->location() == extensions::Manifest::COMPONENT) {
48     // This shouldn't be called for component extensions unless it is called
49     // by sync, for syncable component extensions.
50     // See http://crbug.com/112290 and associated CLs for the sordid history.
51     DCHECK(extensions::sync_helper::IsSyncable(extension));
52 
53     // If we are here, make sure the we aren't trying to change the value.
54     DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, service));
55     return;
56   }
57 
58   ExtensionPrefs* extension_prefs = service->extension_prefs();
59   // Broadcast unloaded and loaded events to update browser state. Only bother
60   // if the value changed and the extension is actually enabled, since there is
61   // no UI otherwise.
62   bool old_enabled = extension_prefs->IsIncognitoEnabled(extension_id);
63   if (enabled == old_enabled)
64     return;
65 
66   extension_prefs->SetIsIncognitoEnabled(extension_id, enabled);
67 
68   bool extension_is_enabled = service->extensions()->Contains(extension_id);
69 
70   // When we reload the extension the ID may be invalidated if we've passed it
71   // by const ref everywhere. Make a copy to be safe.
72   std::string id = extension_id;
73   if (extension_is_enabled)
74     service->ReloadExtension(id);
75 
76   // Reloading the extension invalidates the |extension| pointer.
77   extension = service->GetInstalledExtension(id);
78   if (extension) {
79     ExtensionSyncService::Get(service->profile())->
80         SyncExtensionChangeIfNeeded(*extension);
81   }
82 }
83 
CanCrossIncognito(const Extension * extension,const ExtensionService * service)84 bool CanCrossIncognito(const Extension* extension,
85                        const ExtensionService* service) {
86   // We allow the extension to see events and data from another profile iff it
87   // uses "spanning" behavior and it has incognito access. "split" mode
88   // extensions only see events for a matching profile.
89   CHECK(extension);
90   return extension_util::IsIncognitoEnabled(extension->id(), service) &&
91          !extensions::IncognitoInfo::IsSplitMode(extension);
92 }
93 
CanLoadInIncognito(const Extension * extension,const ExtensionService * service)94 bool CanLoadInIncognito(const Extension* extension,
95                         const ExtensionService* service) {
96   if (extension->is_hosted_app())
97     return true;
98   // Packaged apps and regular extensions need to be enabled specifically for
99   // incognito (and split mode should be set).
100   return extensions::IncognitoInfo::IsSplitMode(extension) &&
101          extension_util::IsIncognitoEnabled(extension->id(), service);
102 }
103 
AllowFileAccess(const Extension * extension,const ExtensionService * service)104 bool AllowFileAccess(const Extension* extension,
105                      const ExtensionService* service) {
106   return (CommandLine::ForCurrentProcess()->HasSwitch(
107               switches::kDisableExtensionsFileAccessCheck) ||
108           service->extension_prefs()->AllowFileAccess(extension->id()));
109 }
110 
SetAllowFileAccess(const Extension * extension,ExtensionService * service,bool allow)111 void SetAllowFileAccess(const Extension* extension,
112                         ExtensionService* service,
113                         bool allow) {
114   // Reload to update browser state. Only bother if the value changed and the
115   // extension is actually enabled, since there is no UI otherwise.
116   bool old_allow = AllowFileAccess(extension, service);
117   if (allow == old_allow)
118     return;
119 
120   service->extension_prefs()->SetAllowFileAccess(extension->id(), allow);
121 
122   bool extension_is_enabled = service->extensions()->Contains(extension->id());
123   if (extension_is_enabled)
124     service->ReloadExtension(extension->id());
125 }
126 
IsAppLaunchable(const std::string & extension_id,const ExtensionService * service)127 bool IsAppLaunchable(const std::string& extension_id,
128                      const ExtensionService* service) {
129   return !(service->extension_prefs()->GetDisableReasons(extension_id) &
130            Extension::DISABLE_UNSUPPORTED_REQUIREMENT);
131 }
132 
IsAppLaunchableWithoutEnabling(const std::string & extension_id,const ExtensionService * service)133 bool IsAppLaunchableWithoutEnabling(const std::string& extension_id,
134                                     const ExtensionService* service) {
135   const Extension* launchable_extension = service->GetExtensionById(
136       extension_id, ExtensionService::INCLUDE_ENABLED);
137   return launchable_extension != NULL;
138 }
139 
140 }  // namespace extension_util
141