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_service.h"
12 #include "chrome/browser/extensions/extension_util.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "extensions/browser/event_router.h"
15 #include "extensions/browser/extension_prefs.h"
16 #include "extensions/browser/extension_system.h"
17 #include "extensions/common/manifest_handlers/incognito_info.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(
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))
95 ExtensionService* extension_service =
96 ExtensionSystem::Get(profile)->extension_service();
97 const ExtensionSet* extensions = extension_service->extensions();
98 for (ExtensionSet::const_iterator it = extensions->begin();
99 it != extensions->end(); ++it) {
100 std::string extension_id = (*it)->id();
101 // TODO(bauerb): Only iterate over registered event listeners.
102 if (router->ExtensionHasEventListener(extension_id, event_name) &&
103 (*it)->HasAPIPermission(permission) &&
104 (!incognito || IncognitoInfo::IsSplitMode(it->get()) ||
105 util::CanCrossIncognito(it->get(), profile))) {
106 // Inject level of control key-value.
107 base::DictionaryValue* dict;
108 bool rv = args->GetDictionary(0, &dict);
110 std::string level_of_control =
111 GetLevelOfControl(profile, extension_id, browser_pref, incognito);
112 dict->SetString(kLevelOfControlKey, level_of_control);
114 // If the extension is in incognito split mode,
115 // a) incognito pref changes are visible only to the incognito tabs
116 // b) regular pref changes are visible only to the incognito tabs if the
117 // incognito pref has not alredy been set
118 Profile* restrict_to_profile = NULL;
119 bool from_incognito = false;
120 if (IncognitoInfo::IsSplitMode(it->get())) {
122 util::IsIncognitoEnabled(extension_id, profile)) {
123 restrict_to_profile = profile->GetOffTheRecordProfile();
124 } else if (!incognito &&
125 PreferenceAPI::Get(profile)->DoesExtensionControlPref(
130 restrict_to_profile = profile;
134 scoped_ptr<base::ListValue> args_copy(args->DeepCopy());
135 scoped_ptr<Event> event(new Event(event_name, args_copy.Pass()));
136 event->restrict_to_browser_context = restrict_to_profile;
137 router->DispatchEventToExtension(extension_id, event.Pass());
142 } // namespace preference_helpers
143 } // namespace extensions