// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/extensions/api/preference/preference_helpers.h" #include "base/json/json_writer.h" #include "base/values.h" #include "chrome/browser/extensions/event_router.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" namespace extensions { namespace preference_helpers { namespace { const char kIncognitoPersistent[] = "incognito_persistent"; const char kIncognitoSessionOnly[] = "incognito_session_only"; const char kRegular[] = "regular"; const char kRegularOnly[] = "regular_only"; const char kLevelOfControlKey[] = "levelOfControl"; const char kNotControllable[] = "not_controllable"; const char kControlledByOtherExtensions[] = "controlled_by_other_extensions"; const char kControllableByThisExtension[] = "controllable_by_this_extension"; const char kControlledByThisExtension[] = "controlled_by_this_extension"; } // namespace bool StringToScope(const std::string& s, extensions::ExtensionPrefsScope* scope) { if (s == kRegular) *scope = extensions::kExtensionPrefsScopeRegular; else if (s == kRegularOnly) *scope = extensions::kExtensionPrefsScopeRegularOnly; else if (s == kIncognitoPersistent) *scope = extensions::kExtensionPrefsScopeIncognitoPersistent; else if (s == kIncognitoSessionOnly) *scope = extensions::kExtensionPrefsScopeIncognitoSessionOnly; else return false; return true; } const char* GetLevelOfControl( Profile* profile, const std::string& extension_id, const std::string& browser_pref, bool incognito) { PrefService* prefs = incognito ? profile->GetOffTheRecordPrefs() : profile->GetPrefs(); bool from_incognito = false; bool* from_incognito_ptr = incognito ? &from_incognito : NULL; const PrefService::Preference* pref = prefs->FindPreference(browser_pref.c_str()); CHECK(pref); extensions::ExtensionPrefs* ep = profile->GetExtensionService()->extension_prefs(); if (!pref->IsExtensionModifiable()) return kNotControllable; if (ep->DoesExtensionControlPref(extension_id, browser_pref, from_incognito_ptr)) { return kControlledByThisExtension; } if (ep->CanExtensionControlPref(extension_id, browser_pref, incognito)) return kControllableByThisExtension; return kControlledByOtherExtensions; } void DispatchEventToExtensions( Profile* profile, const std::string& event_name, ListValue* args, extensions::APIPermission::ID permission, bool incognito, const std::string& browser_pref) { extensions::EventRouter* router = profile->GetExtensionEventRouter(); if (!router || !router->HasEventListener(event_name)) return; ExtensionService* extension_service = profile->GetExtensionService(); const ExtensionSet* extensions = extension_service->extensions(); extensions::ExtensionPrefs* extension_prefs = extension_service->extension_prefs(); for (ExtensionSet::const_iterator it = extensions->begin(); it != extensions->end(); ++it) { std::string extension_id = (*it)->id(); // TODO(bauerb): Only iterate over registered event listeners. if (router->ExtensionHasEventListener(extension_id, event_name) && (*it)->HasAPIPermission(permission) && (!incognito || (*it)->incognito_split_mode() || extension_service->CanCrossIncognito(*it))) { // Inject level of control key-value. DictionaryValue* dict; bool rv = args->GetDictionary(0, &dict); DCHECK(rv); std::string level_of_control = GetLevelOfControl(profile, extension_id, browser_pref, incognito); dict->SetString(kLevelOfControlKey, level_of_control); // If the extension is in incognito split mode, // a) incognito pref changes are visible only to the incognito tabs // b) regular pref changes are visible only to the incognito tabs if the // incognito pref has not alredy been set Profile* restrict_to_profile = NULL; bool from_incognito = false; if ((*it)->incognito_split_mode()) { if (incognito && extension_service->IsIncognitoEnabled(extension_id)) { restrict_to_profile = profile->GetOffTheRecordProfile(); } else if (!incognito && extension_prefs->DoesExtensionControlPref( extension_id, browser_pref, &from_incognito) && from_incognito) { restrict_to_profile = profile; } } scoped_ptr args_copy(args->DeepCopy()); router->DispatchEventToExtension( extension_id, event_name, args_copy.Pass(), restrict_to_profile, GURL()); } } } } // namespace preference_helpers } // namespace extensions