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