Home | History | Annotate | Download | only in preference
      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