Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 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/extension_pref_value_map.h"
      6 
      7 #include "base/stl_util-inl.h"
      8 #include "base/values.h"
      9 #include "chrome/browser/prefs/pref_value_map.h"
     10 
     11 struct ExtensionPrefValueMap::ExtensionEntry {
     12   // Installation time of the extension.
     13   base::Time install_time;
     14   // Whether extension is enabled in the profile.
     15   bool enabled;
     16   // Regular preferences.
     17   PrefValueMap reg_preferences;
     18   // Incognito preferences, empty for regular ExtensionPrefStore.
     19   PrefValueMap inc_preferences;
     20 };
     21 
     22 ExtensionPrefValueMap::ExtensionPrefValueMap() {
     23 }
     24 
     25 ExtensionPrefValueMap::~ExtensionPrefValueMap() {
     26   NotifyOfDestruction();
     27   STLDeleteValues(&entries_);
     28   entries_.clear();
     29 }
     30 
     31 void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id,
     32                                              const std::string& key,
     33                                              bool incognito,
     34                                              Value* value) {
     35   PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, incognito);
     36 
     37   if (prefs->SetValue(key, value))
     38     NotifyPrefValueChanged(key);
     39 }
     40 
     41 void ExtensionPrefValueMap::RemoveExtensionPref(const std::string& ext_id,
     42                                                 const std::string& key,
     43                                                 bool incognito) {
     44   PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, incognito);
     45   if (prefs->RemoveValue(key))
     46     NotifyPrefValueChanged(key);
     47 }
     48 
     49 bool ExtensionPrefValueMap::CanExtensionControlPref(
     50     const std::string& extension_id,
     51     const std::string& pref_key,
     52     bool incognito) const {
     53   ExtensionEntryMap::const_iterator ext = entries_.find(extension_id);
     54   if (ext == entries_.end()) {
     55     NOTREACHED();
     56     return false;
     57   }
     58 
     59   ExtensionEntryMap::const_iterator winner =
     60       GetEffectivePrefValueController(pref_key, incognito, NULL);
     61   if (winner == entries_.end())
     62     return true;
     63 
     64   return winner->second->install_time <= ext->second->install_time;
     65 }
     66 
     67 bool ExtensionPrefValueMap::DoesExtensionControlPref(
     68     const std::string& extension_id,
     69     const std::string& pref_key,
     70     bool incognito) const {
     71   ExtensionEntryMap::const_iterator winner =
     72       GetEffectivePrefValueController(pref_key, incognito, NULL);
     73   if (winner == entries_.end())
     74     return false;
     75   return winner->first == extension_id;
     76 }
     77 
     78 void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id,
     79                                               const base::Time& install_time,
     80                                               bool is_enabled) {
     81   if (entries_.find(ext_id) != entries_.end())
     82     UnregisterExtension(ext_id);
     83   entries_[ext_id] = new ExtensionEntry;
     84   entries_[ext_id]->install_time = install_time;
     85   entries_[ext_id]->enabled = is_enabled;
     86 }
     87 
     88 void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
     89   ExtensionEntryMap::iterator i = entries_.find(ext_id);
     90   if (i == entries_.end())
     91     return;
     92   std::set<std::string> keys;  // keys set by this extension
     93   GetExtensionControlledKeys(*(i->second), &keys);
     94 
     95   delete i->second;
     96   entries_.erase(i);
     97 
     98   NotifyPrefValueChanged(keys);
     99 }
    100 
    101 void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
    102                                               bool is_enabled) {
    103   ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
    104   CHECK(i != entries_.end());
    105   if (i->second->enabled == is_enabled)
    106     return;
    107   std::set<std::string> keys;  // keys set by this extension
    108   GetExtensionControlledKeys(*(i->second), &keys);
    109   i->second->enabled = is_enabled;
    110   NotifyPrefValueChanged(keys);
    111 }
    112 
    113 PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
    114     const std::string& ext_id,
    115     bool incognito) {
    116   ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
    117   CHECK(i != entries_.end());
    118   return incognito ? &(i->second->inc_preferences)
    119                    : &(i->second->reg_preferences);
    120 }
    121 
    122 const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
    123     const std::string& ext_id,
    124     bool incognito) const {
    125   ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
    126   CHECK(i != entries_.end());
    127   return incognito ? &(i->second->inc_preferences)
    128                    : &(i->second->reg_preferences);
    129 }
    130 
    131 void ExtensionPrefValueMap::GetExtensionControlledKeys(
    132     const ExtensionEntry& entry,
    133     std::set<std::string>* out) const {
    134   PrefValueMap::const_iterator i;
    135 
    136   const PrefValueMap& reg_prefs = entry.reg_preferences;
    137   for (i = reg_prefs.begin(); i != reg_prefs.end(); ++i)
    138     out->insert(i->first);
    139 
    140   const PrefValueMap& inc_prefs = entry.inc_preferences;
    141   for (i = inc_prefs.begin(); i != inc_prefs.end(); ++i)
    142     out->insert(i->first);
    143 }
    144 
    145 const Value* ExtensionPrefValueMap::GetEffectivePrefValue(
    146     const std::string& key,
    147     bool incognito,
    148     bool* from_incognito) const {
    149   ExtensionEntryMap::const_iterator winner =
    150       GetEffectivePrefValueController(key, incognito, from_incognito);
    151   if (winner == entries_.end())
    152     return NULL;
    153 
    154   const Value* value = NULL;
    155   const std::string& ext_id = winner->first;
    156   if (incognito)
    157     GetExtensionPrefValueMap(ext_id, true)->GetValue(key, &value);
    158   if (!value)
    159     GetExtensionPrefValueMap(ext_id, false)->GetValue(key, &value);
    160   return value;
    161 }
    162 
    163 ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
    164 ExtensionPrefValueMap::GetEffectivePrefValueController(
    165     const std::string& key,
    166     bool incognito,
    167     bool* from_incognito) const {
    168   ExtensionEntryMap::const_iterator winner = entries_.end();
    169   base::Time winners_install_time;
    170 
    171   ExtensionEntryMap::const_iterator i;
    172   for (i = entries_.begin(); i != entries_.end(); ++i) {
    173     const std::string& ext_id = i->first;
    174     const base::Time& install_time = i->second->install_time;
    175     const bool enabled = i->second->enabled;
    176 
    177     if (!enabled)
    178       continue;
    179     if (install_time < winners_install_time)
    180       continue;
    181 
    182     const Value* value = NULL;
    183     const PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, false);
    184     if (prefs->GetValue(key, &value)) {
    185       winner = i;
    186       winners_install_time = install_time;
    187       if (from_incognito)
    188         *from_incognito = false;
    189     }
    190 
    191     if (!incognito)
    192       continue;
    193 
    194     prefs = GetExtensionPrefValueMap(ext_id, true);
    195     if (prefs->GetValue(key, &value)) {
    196       winner = i;
    197       winners_install_time = install_time;
    198       if (from_incognito)
    199         *from_incognito = true;
    200     }
    201   }
    202   return winner;
    203 }
    204 
    205 void ExtensionPrefValueMap::AddObserver(
    206     ExtensionPrefValueMap::Observer* observer) {
    207   observers_.AddObserver(observer);
    208 
    209   // Collect all currently used keys and notify the new observer.
    210   std::set<std::string> keys;
    211   ExtensionEntryMap::const_iterator i;
    212   for (i = entries_.begin(); i != entries_.end(); ++i)
    213     GetExtensionControlledKeys(*(i->second), &keys);
    214 
    215   std::set<std::string>::const_iterator j;
    216   for (j = keys.begin(); j != keys.end(); ++j)
    217     observer->OnPrefValueChanged(*j);
    218 }
    219 
    220 void ExtensionPrefValueMap::RemoveObserver(
    221     ExtensionPrefValueMap::Observer* observer) {
    222   observers_.RemoveObserver(observer);
    223 }
    224 
    225 void ExtensionPrefValueMap::NotifyInitializationCompleted() {
    226   FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
    227                     OnInitializationCompleted());
    228 }
    229 
    230 void ExtensionPrefValueMap::NotifyPrefValueChanged(
    231     const std::set<std::string>& keys) {
    232   std::set<std::string>::const_iterator i;
    233   for (i = keys.begin(); i != keys.end(); ++i)
    234     NotifyPrefValueChanged(*i);
    235 }
    236 
    237 void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
    238   FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
    239                     OnPrefValueChanged(key));
    240 }
    241 
    242 void ExtensionPrefValueMap::NotifyOfDestruction() {
    243   FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
    244                     OnExtensionPrefValueMapDestruction());
    245 }
    246