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. 4 5 #include "chrome/browser/extensions/api/preference/preference_helpers.h" 6 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/event_router.h" 12 #include "chrome/browser/extensions/extension_prefs.h" 13 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/browser/extensions/extension_system.h" 15 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/common/extensions/incognito_handler.h" 17 18 namespace extensions { 19 namespace preference_helpers { 20 21 namespace { 22 23 const char kIncognitoPersistent[] = "incognito_persistent"; 24 const char kIncognitoSessionOnly[] = "incognito_session_only"; 25 const char kRegular[] = "regular"; 26 const char kRegularOnly[] = "regular_only"; 27 28 const char kLevelOfControlKey[] = "levelOfControl"; 29 30 const char kNotControllable[] = "not_controllable"; 31 const char kControlledByOtherExtensions[] = "controlled_by_other_extensions"; 32 const char kControllableByThisExtension[] = "controllable_by_this_extension"; 33 const char kControlledByThisExtension[] = "controlled_by_this_extension"; 34 35 } // namespace 36 37 bool StringToScope(const std::string& s, 38 ExtensionPrefsScope* scope) { 39 if (s == kRegular) 40 *scope = kExtensionPrefsScopeRegular; 41 else if (s == kRegularOnly) 42 *scope = kExtensionPrefsScopeRegularOnly; 43 else if (s == kIncognitoPersistent) 44 *scope = kExtensionPrefsScopeIncognitoPersistent; 45 else if (s == kIncognitoSessionOnly) 46 *scope = kExtensionPrefsScopeIncognitoSessionOnly; 47 else 48 return false; 49 return true; 50 } 51 52 const char* GetLevelOfControl( 53 Profile* profile, 54 const std::string& extension_id, 55 const std::string& browser_pref, 56 bool incognito) { 57 PrefService* prefs = incognito ? profile->GetOffTheRecordPrefs() 58 : profile->GetPrefs(); 59 bool from_incognito = false; 60 bool* from_incognito_ptr = incognito ? &from_incognito : NULL; 61 const PrefService::Preference* pref = 62 prefs->FindPreference(browser_pref.c_str()); 63 CHECK(pref); 64 65 if (!pref->IsExtensionModifiable()) 66 return kNotControllable; 67 68 if (PreferenceAPI::Get(profile)->DoesExtensionControlPref( 69 extension_id, 70 browser_pref, 71 from_incognito_ptr)) { 72 return kControlledByThisExtension; 73 } 74 75 if (PreferenceAPI::Get(profile)->CanExtensionControlPref(extension_id, 76 browser_pref, 77 incognito)) { 78 return kControllableByThisExtension; 79 } 80 81 return kControlledByOtherExtensions; 82 } 83 84 void DispatchEventToExtensions( 85 Profile* profile, 86 const std::string& event_name, 87 base::ListValue* args, 88 APIPermission::ID permission, 89 bool incognito, 90 const std::string& browser_pref) { 91 EventRouter* router = 92 ExtensionSystem::Get(profile)->event_router(); 93 if (!router || !router->HasEventListener(event_name)) 94 return; 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 extension_service->CanCrossIncognito(it->get()))) { 106 // Inject level of control key-value. 107 base::DictionaryValue* dict; 108 bool rv = args->GetDictionary(0, &dict); 109 DCHECK(rv); 110 std::string level_of_control = 111 GetLevelOfControl(profile, extension_id, browser_pref, incognito); 112 dict->SetString(kLevelOfControlKey, level_of_control); 113 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())) { 121 if (incognito && extension_service->IsIncognitoEnabled(extension_id)) { 122 restrict_to_profile = profile->GetOffTheRecordProfile(); 123 } else if (!incognito && 124 PreferenceAPI::Get(profile)->DoesExtensionControlPref( 125 extension_id, 126 browser_pref, 127 &from_incognito) && 128 from_incognito) { 129 restrict_to_profile = profile; 130 } 131 } 132 133 scoped_ptr<base::ListValue> args_copy(args->DeepCopy()); 134 scoped_ptr<Event> event(new Event(event_name, args_copy.Pass())); 135 event->restrict_to_profile = restrict_to_profile; 136 router->DispatchEventToExtension(extension_id, event.Pass()); 137 } 138 } 139 } 140 141 } // namespace preference_helpers 142 } // namespace extensions 143