1 // Copyright (c) 2012 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/api/preference/preference_helpers.h"
7 #include "base/json/json_writer.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/values.h"
10 #include "chrome/browser/extensions/api/preference/preference_api.h"
11 #include "chrome/browser/extensions/extension_util.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "extensions/browser/event_router.h"
14 #include "extensions/browser/extension_prefs.h"
15 #include "extensions/browser/extension_registry.h"
16 #include "extensions/common/manifest_handlers/incognito_info.h"
17 #include "extensions/common/permissions/permissions_data.h"
19 namespace extensions
{
20 namespace preference_helpers
{
24 const char kIncognitoPersistent
[] = "incognito_persistent";
25 const char kIncognitoSessionOnly
[] = "incognito_session_only";
26 const char kRegular
[] = "regular";
27 const char kRegularOnly
[] = "regular_only";
29 const char kLevelOfControlKey
[] = "levelOfControl";
31 const char kNotControllable
[] = "not_controllable";
32 const char kControlledByOtherExtensions
[] = "controlled_by_other_extensions";
33 const char kControllableByThisExtension
[] = "controllable_by_this_extension";
34 const char kControlledByThisExtension
[] = "controlled_by_this_extension";
38 bool StringToScope(const std::string
& s
,
39 ExtensionPrefsScope
* scope
) {
41 *scope
= kExtensionPrefsScopeRegular
;
42 else if (s
== kRegularOnly
)
43 *scope
= kExtensionPrefsScopeRegularOnly
;
44 else if (s
== kIncognitoPersistent
)
45 *scope
= kExtensionPrefsScopeIncognitoPersistent
;
46 else if (s
== kIncognitoSessionOnly
)
47 *scope
= kExtensionPrefsScopeIncognitoSessionOnly
;
53 const char* GetLevelOfControl(
55 const std::string
& extension_id
,
56 const std::string
& browser_pref
,
58 PrefService
* prefs
= incognito
? profile
->GetOffTheRecordPrefs()
59 : profile
->GetPrefs();
60 bool from_incognito
= false;
61 bool* from_incognito_ptr
= incognito
? &from_incognito
: NULL
;
62 const PrefService::Preference
* pref
=
63 prefs
->FindPreference(browser_pref
.c_str());
66 if (!pref
->IsExtensionModifiable())
67 return kNotControllable
;
69 if (PreferenceAPI::Get(profile
)->DoesExtensionControlPref(
72 from_incognito_ptr
)) {
73 return kControlledByThisExtension
;
76 if (PreferenceAPI::Get(profile
)->CanExtensionControlPref(extension_id
,
79 return kControllableByThisExtension
;
82 return kControlledByOtherExtensions
;
85 void DispatchEventToExtensions(Profile
* profile
,
86 events::HistogramValue histogram_value
,
87 const std::string
& event_name
,
88 base::ListValue
* args
,
89 APIPermission::ID permission
,
91 const std::string
& browser_pref
) {
92 EventRouter
* router
= EventRouter::Get(profile
);
93 if (!router
|| !router
->HasEventListener(event_name
))
96 for (const scoped_refptr
<const extensions::Extension
>& extension
:
97 ExtensionRegistry::Get(profile
)->enabled_extensions()) {
98 // TODO(bauerb): Only iterate over registered event listeners.
99 if (router
->ExtensionHasEventListener(extension
->id(), event_name
) &&
100 extension
->permissions_data()->HasAPIPermission(permission
) &&
101 (!incognito
|| IncognitoInfo::IsSplitMode(extension
.get()) ||
102 util::CanCrossIncognito(extension
.get(), profile
))) {
103 // Inject level of control key-value.
104 base::DictionaryValue
* dict
;
105 bool rv
= args
->GetDictionary(0, &dict
);
107 std::string level_of_control
=
108 GetLevelOfControl(profile
, extension
->id(), browser_pref
, incognito
);
109 dict
->SetString(kLevelOfControlKey
, level_of_control
);
111 // If the extension is in incognito split mode,
112 // a) incognito pref changes are visible only to the incognito tabs
113 // b) regular pref changes are visible only to the incognito tabs if the
114 // incognito pref has not alredy been set
115 Profile
* restrict_to_profile
= NULL
;
116 bool from_incognito
= false;
117 if (IncognitoInfo::IsSplitMode(extension
.get())) {
118 if (incognito
&& util::IsIncognitoEnabled(extension
->id(), profile
)) {
119 restrict_to_profile
= profile
->GetOffTheRecordProfile();
120 } else if (!incognito
&&
121 PreferenceAPI::Get(profile
)->DoesExtensionControlPref(
122 extension
->id(), browser_pref
, &from_incognito
) &&
124 restrict_to_profile
= profile
;
128 scoped_ptr
<base::ListValue
> args_copy(args
->DeepCopy());
129 scoped_ptr
<Event
> event(
130 new Event(histogram_value
, event_name
, args_copy
.Pass()));
131 event
->restrict_to_browser_context
= restrict_to_profile
;
132 router
->DispatchEventToExtension(extension
->id(), event
.Pass());
137 } // namespace preference_helpers
138 } // namespace extensions