• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_VALUE_MAP_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_VALUE_MAP_H_
7 #pragma once
8 
9 #include <map>
10 #include <set>
11 #include <string>
12 
13 #include "base/time.h"
14 #include "chrome/browser/prefs/value_map_pref_store.h"
15 
16 // Non-persistent data container that is shared by ExtensionPrefStores. All
17 // extension pref values (incognito and regular) are stored herein and
18 // provided to ExtensionPrefStores.
19 //
20 // The semantics of the ExtensionPrefValueMap are:
21 // - The precedence of extensions is determined by their installation time.
22 //   The extension that has been installed later takes higher precedence.
23 // - If two extensions set a value for the same preference, the following
24 //   rules determine which value becomes effective (visible).
25 // - The effective regular extension pref value is determined by the regular
26 //   extension pref value of the extension with the highest precedence.
27 // - The effective incognito extension pref value is determined by the incognito
28 //   extension pref value of the extension with the highest precedence, unless
29 //   another extension with higher precedence overrides it with a regular
30 //   extension pref value.
31 //
32 // The following table illustrates the behavior:
33 //   A.reg | A.inc | B.reg | B.inc | E.reg | E.inc
34 //     1   |   -   |   -   |   -   |   1   |   1
35 //     1   |   2   |   -   |   -   |   1   |   2
36 //     1   |   -   |   3   |   -   |   3   |   3
37 //     1   |   -   |   -   |   4   |   1   |   4
38 //     1   |   2   |   3   |   -   |   3   |   3(!)
39 //     1   |   2   |   -   |   4   |   1   |   4
40 //     1   |   2   |   3   |   4   |   3   |   4
41 // A = extension A, B = extension B, E = effective value
42 // .reg = regular value
43 // .inc = incognito value
44 // Extension B has higher precedence than A.
45 class ExtensionPrefValueMap {
46  public:
47   // Observer interface for monitoring ExtensionPrefValueMap.
48   class Observer {
49    public:
~Observer()50     virtual ~Observer() {}
51 
52     // Called when the value for the given |key| set by one of the extensions
53     // changes. This does not necessarily mean that the effective value has
54     // changed.
55     virtual void OnPrefValueChanged(const std::string& key) = 0;
56     // Notification about the ExtensionPrefValueMap being fully initialized.
57     virtual void OnInitializationCompleted() = 0;
58     // Called when the ExtensionPrefValueMap is being destroyed. When called,
59     // observers must unsubscribe.
60     virtual void OnExtensionPrefValueMapDestruction() = 0;
61   };
62 
63   ExtensionPrefValueMap();
64   virtual ~ExtensionPrefValueMap();
65 
66   // Set an extension preference |value| for |key| of extension |ext_id|.
67   // Takes ownership of |value|.
68   // Note that regular extension pref values need to be reported to
69   // incognito and to regular ExtensionPrefStores.
70   // Precondition: the extension must be registered.
71   void SetExtensionPref(const std::string& ext_id,
72                         const std::string& key,
73                         bool incognito,
74                         Value* value);
75 
76   // Remove the extension preference value for |key| of extension |ext_id|.
77   // Precondition: the extension must be registered.
78   void RemoveExtensionPref(const std::string& ext_id,
79                            const std::string& key,
80                            bool incognito);
81 
82   // Returns true if currently no extension with higher precedence controls the
83   // preference.
84   // Note that the this function does does not consider the existence of
85   // policies. An extension is only really able to control a preference if
86   // PrefService::Preference::IsExtensionModifiable() returns true as well.
87   bool CanExtensionControlPref(const std::string& extension_id,
88                                const std::string& pref_key,
89                                bool incognito) const;
90 
91   // Returns true if an extension identified by |extension_id| controls the
92   // preference. This means this extension has set a preference value and no
93   // other extension with higher precedence overrides it.
94   // Note that the this function does does not consider the existence of
95   // policies. An extension is only really able to control a preference if
96   // PrefService::Preference::IsExtensionModifiable() returns true as well.
97   bool DoesExtensionControlPref(const std::string& extension_id,
98                                 const std::string& pref_key,
99                                 bool incognito) const;
100 
101   // Tell the store it's now fully initialized.
102   void NotifyInitializationCompleted();
103 
104   // Registers the time when an extension |ext_id| is installed.
105   void RegisterExtension(const std::string& ext_id,
106                          const base::Time& install_time,
107                          bool is_enabled);
108 
109   // Deletes all entries related to extension |ext_id|.
110   void UnregisterExtension(const std::string& ext_id);
111 
112   // Hides or makes the extension preference values of the specified extension
113   // visible.
114   void SetExtensionState(const std::string& ext_id, bool is_enabled);
115 
116   // Adds an observer and notifies it about the currently stored keys.
117   void AddObserver(Observer* observer);
118 
119   void RemoveObserver(Observer* observer);
120 
121   const Value* GetEffectivePrefValue(const std::string& key,
122                                      bool incognito,
123                                      bool* from_incognito) const;
124 
125  private:
126   struct ExtensionEntry;
127 
128   typedef std::map<std::string, ExtensionEntry*> ExtensionEntryMap;
129 
130   const PrefValueMap* GetExtensionPrefValueMap(const std::string& ext_id,
131                                                bool incognito) const;
132 
133   PrefValueMap* GetExtensionPrefValueMap(const std::string& ext_id,
134                                          bool incognito);
135 
136   // Returns all keys of pref values that are set by the extension of |entry|,
137   // regardless whether they are set for incognito or regular pref values.
138   void GetExtensionControlledKeys(const ExtensionEntry& entry,
139                                   std::set<std::string>* out) const;
140 
141   // Returns an iterator to the extension which controls the preference |key|.
142   // If |incognito| is true, looks at incognito preferences first. In that case,
143   // if |from_incognito| is not NULL, it is set to true if the effective pref
144   // value is coming from the incognito preferences, false if it is coming from
145   // the normal ones.
146   ExtensionEntryMap::const_iterator GetEffectivePrefValueController(
147       const std::string& key,
148       bool incognito,
149       bool* from_incognito) const;
150 
151   void NotifyOfDestruction();
152   void NotifyPrefValueChanged(const std::string& key);
153   void NotifyPrefValueChanged(const std::set<std::string>& keys);
154 
155   // Mapping of which extension set which preference value. The effective
156   // preferences values (i.e. the ones with the highest precedence)
157   // are stored in ExtensionPrefStores.
158   ExtensionEntryMap entries_;
159 
160   ObserverList<Observer, true> observers_;
161 
162   DISALLOW_COPY_AND_ASSIGN(ExtensionPrefValueMap);
163 };
164 
165 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_VALUE_MAP_H_
166