• 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_PREFS_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_PREFS_H_
7 #pragma once
8 
9 #include <set>
10 #include <string>
11 #include <vector>
12 
13 #include "base/memory/linked_ptr.h"
14 #include "base/time.h"
15 #include "chrome/browser/prefs/pref_service.h"
16 #include "chrome/common/extensions/extension.h"
17 #include "googleurl/src/gurl.h"
18 
19 class ExtensionPrefValueMap;
20 
21 // Class for managing global and per-extension preferences.
22 //
23 // This class distinguishes the following kinds of preferences:
24 // - global preferences:
25 //       internal state for the extension system in general, not associated
26 //       with an individual extension, such as lastUpdateTime.
27 // - per-extension preferences:
28 //       meta-preferences describing properties of the extension like
29 //       installation time, whether the extension is enabled, etc.
30 // - extension controlled preferences:
31 //       browser preferences that an extension controls. For example, an
32 //       extension could use the proxy API to specify the browser's proxy
33 //       preference. Extension-controlled preferences are stored in
34 //       PrefValueStore::extension_prefs(), which this class populates and
35 //       maintains as the underlying extensions change.
36 class ExtensionPrefs {
37  public:
38   // Key name for a preference that keeps track of per-extension settings. This
39   // is a dictionary object read from the Preferences file, keyed off of
40   // extension ids.
41   static const char kExtensionsPref[];
42 
43   typedef std::vector<linked_ptr<ExtensionInfo> > ExtensionsInfo;
44 
45   // Vector containing identifiers for preferences.
46   typedef std::set<std::string> PrefKeySet;
47 
48   // Vector containing identifiers for extensions.
49   typedef std::vector<std::string> ExtensionIdSet;
50 
51   // This enum is used for the launch type the user wants to use for an
52   // application.
53   // Do not remove items or re-order this enum as it is used in preferences
54   // and histograms.
55   enum LaunchType {
56     LAUNCH_PINNED,
57     LAUNCH_REGULAR,
58     LAUNCH_FULLSCREEN,
59     LAUNCH_WINDOW,
60 
61     // Launch an app in the in the way a click on the NTP would,
62     // if no user pref were set.  Update this constant to change
63     // the default for the NTP and chrome.management.launchApp().
64     LAUNCH_DEFAULT = LAUNCH_REGULAR
65   };
66 
67   // Does not assume ownership of |prefs| and |incognito_prefs|.
68   explicit ExtensionPrefs(PrefService* prefs,
69                           const FilePath& root_dir,
70                           ExtensionPrefValueMap* extension_pref_value_map);
71   virtual ~ExtensionPrefs();
72 
73   // Returns a copy of the Extensions prefs.
74   // TODO(erikkay) Remove this so that external consumers don't need to be
75   // aware of the internal structure of the preferences.
76   DictionaryValue* CopyCurrentExtensions();
77 
78   // Returns true if the specified external extension was uninstalled by the
79   // user.
80   bool IsExternalExtensionUninstalled(const std::string& id) const;
81 
82   // Get the order that toolstrip URLs appear in the shelf.
83   typedef std::vector<GURL> URLList;
84   URLList GetShelfToolstripOrder();
85 
86   // Sets the order that toolstrip URLs appear in the shelf.
87   void SetShelfToolstripOrder(const URLList& urls);
88 
89   // Get the order that the browser actions appear in the toolbar.
90   std::vector<std::string> GetToolbarOrder();
91 
92   // Set the order that the browser actions appear in the toolbar.
93   void SetToolbarOrder(const std::vector<std::string>& extension_ids);
94 
95   // Called when an extension is installed, so that prefs get created.
96   void OnExtensionInstalled(const Extension* extension,
97                             Extension::State initial_state,
98                             bool initial_incognito_enabled);
99 
100   // Called when an extension is uninstalled, so that prefs get cleaned up.
101   void OnExtensionUninstalled(const std::string& extension_id,
102                               const Extension::Location& location,
103                               bool external_uninstall);
104 
105   // Returns the state (enabled/disabled) of the given extension.
106   Extension::State GetExtensionState(const std::string& extension_id) const;
107 
108   // Called to change the extension's state when it is enabled/disabled.
109   void SetExtensionState(const Extension* extension, Extension::State);
110 
111   // Returns all installed extensions
112   void GetExtensions(ExtensionIdSet* out);
113 
114   // Getter and setter for browser action visibility.
115   bool GetBrowserActionVisibility(const Extension* extension);
116   void SetBrowserActionVisibility(const Extension* extension, bool visible);
117 
118   // Did the extension ask to escalate its permission during an upgrade?
119   bool DidExtensionEscalatePermissions(const std::string& id);
120 
121   // If |did_escalate| is true, the preferences for |extension| will be set to
122   // require the install warning when the user tries to enable.
123   void SetDidExtensionEscalatePermissions(const Extension* extension,
124                                           bool did_escalate);
125 
126   // Returns the version string for the currently installed extension, or
127   // the empty string if not found.
128   std::string GetVersionString(const std::string& extension_id);
129 
130   // Re-writes the extension manifest into the prefs.
131   // Called to change the extension's manifest when it's re-localized.
132   void UpdateManifest(const Extension* extension);
133 
134   // Returns extension path based on extension ID, or empty FilePath on error.
135   FilePath GetExtensionPath(const std::string& extension_id);
136 
137   // Returns base extensions install directory.
install_directory()138   const FilePath& install_directory() const { return install_directory_; }
139 
140   // Updates the prefs based on the blacklist.
141   void UpdateBlacklist(const std::set<std::string>& blacklist_set);
142 
143   // Based on extension id, checks prefs to see if it is blacklisted.
144   bool IsExtensionBlacklisted(const std::string& id);
145 
146   // Is the extension with |extension_id| allowed by policy (checking both
147   // whitelist and blacklist).
148   bool IsExtensionAllowedByPolicy(const std::string& extension_id);
149 
150   // Returns the last value set via SetLastPingDay. If there isn't such a
151   // pref, the returned Time will return true for is_null().
152   base::Time LastPingDay(const std::string& extension_id) const;
153 
154   // The time stored is based on the server's perspective of day start time, not
155   // the client's.
156   void SetLastPingDay(const std::string& extension_id, const base::Time& time);
157 
158   // Similar to the 2 above, but for the extensions blacklist.
159   base::Time BlacklistLastPingDay() const;
160   void SetBlacklistLastPingDay(const base::Time& time);
161 
162   // Similar to LastPingDay/SetLastPingDay, but for sending "days since active"
163   // ping.
164   base::Time LastActivePingDay(const std::string& extension_id);
165   void SetLastActivePingDay(const std::string& extension_id,
166                             const base::Time& time);
167 
168   // A bit we use for determining if we should send the "days since active"
169   // ping. A value of true means the item has been active (launched) since the
170   // last update check.
171   bool GetActiveBit(const std::string& extension_id);
172   void SetActiveBit(const std::string& extension_id, bool active);
173 
174   // Gets the permissions (|api_permissions|, |host_extent| and |full_access|)
175   // granted to the extension with |extension_id|. |full_access| will be true
176   // if the extension has all effective permissions (like from an NPAPI plugin).
177   // Returns false if the granted permissions haven't been initialized yet.
178   // TODO(jstritar): Refactor the permissions into a class that encapsulates
179   // all granted permissions, can be initialized from preferences or
180   // a manifest file, and can be compared to each other.
181   bool GetGrantedPermissions(const std::string& extension_id,
182                              bool* full_access,
183                              std::set<std::string>* api_permissions,
184                              ExtensionExtent* host_extent);
185 
186   // Adds the specified |api_permissions|, |host_extent| and |full_access|
187   // to the granted permissions for extension with |extension_id|.
188   // |full_access| should be set to true if the extension effectively has all
189   // permissions (such as by having an NPAPI plugin).
190   void AddGrantedPermissions(const std::string& extension_id,
191                              const bool full_access,
192                              const std::set<std::string>& api_permissions,
193                              const ExtensionExtent& host_extent);
194 
195   // Returns true if the user enabled this extension to be loaded in incognito
196   // mode.
197   bool IsIncognitoEnabled(const std::string& extension_id);
198   void SetIsIncognitoEnabled(const std::string& extension_id, bool enabled);
199 
200   // Returns true if the user has chosen to allow this extension to inject
201   // scripts into pages with file URLs.
202   bool AllowFileAccess(const std::string& extension_id);
203   void SetAllowFileAccess(const std::string& extension_id, bool allow);
204   bool HasAllowFileAccessSetting(const std::string& extension_id) const;
205 
206   // Get the launch type preference.  If no preference is set, return
207   // |default_pref_value|.
208   LaunchType GetLaunchType(const std::string& extension_id,
209                            LaunchType default_pref_value);
210 
211   void SetLaunchType(const std::string& extension_id, LaunchType launch_type);
212 
213   // Find the right launch container based on the launch type.
214   // If |extension|'s prefs do not have a launch type set, then
215   // use |default_pref_value|.
216   extension_misc::LaunchContainer GetLaunchContainer(
217       const Extension* extension,
218       LaunchType default_pref_value);
219 
220 
221   // Saves ExtensionInfo for each installed extension with the path to the
222   // version directory and the location. Blacklisted extensions won't be saved
223   // and neither will external extensions the user has explicitly uninstalled.
224   // Caller takes ownership of returned structure.
225   ExtensionsInfo* GetInstalledExtensionsInfo();
226 
227   // Returns the ExtensionInfo from the prefs for the given extension. If the
228   // extension is not present, NULL is returned.
229   ExtensionInfo* GetInstalledExtensionInfo(const std::string& extension_id);
230 
231   // We've downloaded an updated .crx file for the extension, but are waiting
232   // for idle time to install it.
233   void SetIdleInstallInfo(const std::string& extension_id,
234                           const FilePath& crx_path,
235                           const std::string& version,
236                           const base::Time& fetch_time);
237 
238   // Removes any idle install information we have for the given |extension_id|.
239   // Returns true if there was info to remove; false otherwise.
240   bool RemoveIdleInstallInfo(const std::string& extension_id);
241 
242   // If we have idle install information for |extension_id|, this puts it into
243   // the out parameters and returns true. Otherwise returns false.
244   bool GetIdleInstallInfo(const std::string& extension_id,
245                           FilePath* crx_path,
246                           std::string* version,
247                           base::Time* fetch_time);
248 
249   // Returns the extension id's that have idle install information.
250   std::set<std::string> GetIdleInstallInfoIds();
251 
252   // We allow the web store to set a string containing login information when a
253   // purchase is made, so that when a user logs into sync with a different
254   // account we can recognize the situation. The Get function returns true if
255   // there was previously stored data (placing it in |result|), or false
256   // otherwise. The Set will overwrite any previous login.
257   bool GetWebStoreLogin(std::string* result);
258   void SetWebStoreLogin(const std::string& login);
259 
260   // Get the application launch index for an extension with |extension_id|. This
261   // determines the order of which the applications appear on the New Tab Page.
262   // A value of 0 generally indicates top left. If the extension has no launch
263   // index a -1 value is returned.
264   int GetAppLaunchIndex(const std::string& extension_id);
265 
266   // Sets a specific launch index for an extension with |extension_id|.
267   void SetAppLaunchIndex(const std::string& extension_id, int index);
268 
269   // Gets the next available application launch index. This is 1 higher than the
270   // highest current application launch index found.
271   int GetNextAppLaunchIndex();
272 
273   // Sets the order the apps should be displayed in the app launcher.
274   void SetAppLauncherOrder(const std::vector<std::string>& extension_ids);
275 
276   // Get the application page index for an extension with |extension_id|.  This
277   // determines which page an app will appear on in page-based NTPs.  If
278   // the app has no page specified, -1 is returned.
279   int GetPageIndex(const std::string& extension_id);
280 
281   // Sets a specific page index for an extension with |extension_id|.
282   void SetPageIndex(const std::string& extension_id, int index);
283 
284   // Returns true if the user repositioned the app on the app launcher via drag
285   // and drop.
286   bool WasAppDraggedByUser(const std::string& extension_id);
287 
288   // Sets a flag indicating that the user repositioned the app on the app
289   // launcher by drag and dropping it.
290   void SetAppDraggedByUser(const std::string& extension_id);
291 
292   // The extension's update URL data.  If not empty, the ExtensionUpdater
293   // will append a ap= parameter to the URL when checking if a new version
294   // of the extension is available.
295   void SetUpdateUrlData(const std::string& extension_id,
296                         const std::string& data);
297   std::string GetUpdateUrlData(const std::string& extension_id);
298 
299   // Sets a preference value that is controlled by the extension. In other
300   // words, this is not a pref value *about* the extension but something
301   // global the extension wants to override.
302   // Takes ownership of |value|.
303   void SetExtensionControlledPref(const std::string& extension_id,
304                                   const std::string& pref_key,
305                                   bool incognito,
306                                   Value* value);
307 
308   void RemoveExtensionControlledPref(const std::string& extension_id,
309                                      const std::string& pref_key,
310                                      bool incognito);
311 
312   // Returns true if currently no extension with higher precedence controls the
313   // preference.
314   bool CanExtensionControlPref(const std::string& extension_id,
315                                const std::string& pref_key,
316                                bool incognito);
317 
318   // Returns true if extension |extension_id| currently controls the
319   // preference.
320   bool DoesExtensionControlPref(const std::string& extension_id,
321                                 const std::string& pref_key,
322                                 bool incognito);
323 
324   // Returns true if there is an extension which controls the preference value
325   //  for |pref_key| *and* it is specific to incognito mode.
326   bool HasIncognitoPrefValue(const std::string& pref_key);
327 
328   static void RegisterUserPrefs(PrefService* prefs);
329 
330   // The underlying PrefService.
pref_service()331   PrefService* pref_service() const { return prefs_; }
332 
333  protected:
334   // For unit testing. Enables injecting an artificial clock that is used
335   // to query the current time, when an extension is installed.
336   virtual base::Time GetCurrentTime() const;
337 
338  private:
339   // Converts absolute paths in the pref to paths relative to the
340   // install_directory_.
341   void MakePathsRelative();
342 
343   // Converts internal relative paths to be absolute. Used for export to
344   // consumers who expect full paths.
345   void MakePathsAbsolute(DictionaryValue* dict);
346 
347   // Sets the pref |key| for extension |id| to |value|.
348   void UpdateExtensionPref(const std::string& id,
349                            const std::string& key,
350                            Value* value);
351 
352   // Deletes the pref dictionary for extension |id|.
353   void DeleteExtensionPrefs(const std::string& id);
354 
355   // Reads a boolean pref from |ext| with key |pref_key|.
356   // Return false if the value is false or |pref_key| does not exist.
357   bool ReadBooleanFromPref(const DictionaryValue* ext,
358                            const std::string& pref_key);
359 
360   // Reads a boolean pref |pref_key| from extension with id |extension_id|.
361   bool ReadExtensionPrefBoolean(const std::string& extension_id,
362                                 const std::string& pref_key);
363 
364   // Reads an integer pref from |ext| with key |pref_key|.
365   // Return false if the value does not exist.
366   bool ReadIntegerFromPref(const DictionaryValue* ext,
367                            const std::string& pref_key,
368                            int* out_value);
369 
370   // Reads an integer pref |pref_key| from extension with id |extension_id|.
371   bool ReadExtensionPrefInteger(const std::string& extension_id,
372                                 const std::string& pref_key,
373                                 int* out_value);
374 
375   // Reads a list pref |pref_key| from extension with id | extension_id|.
376   bool ReadExtensionPrefList(const std::string& extension_id,
377                              const std::string& pref_key,
378                              const ListValue** out_value);
379 
380   // Reads a list pref |pref_key| as a string set from the extension with
381   // id |extension_id|.
382   bool ReadExtensionPrefStringSet(const std::string& extension_id,
383                                   const std::string& pref_key,
384                                   std::set<std::string>* result);
385 
386   // Adds the |added_values| to the value of |pref_key| for the extension
387   // with id |extension_id| (the new value will be the union of the existing
388   // value and |added_values|).
389   void AddToExtensionPrefStringSet(const std::string& extension_id,
390                                    const std::string& pref_key,
391                                    const std::set<std::string>& added_values);
392 
393   // Returns a dictionary for extension |id|'s prefs or NULL if it doesn't
394   // exist.
395   const DictionaryValue* GetExtensionPref(const std::string& id) const;
396 
397   // Returns the dictionary of preferences controlled by the specified extension
398   // or creates a new one. All entries in the dictionary contain non-expanded
399   // paths.
400   const DictionaryValue* GetExtensionControlledPrefs(
401       const std::string& id) const;
402 
403   // Serializes the data and schedules a persistent save via the |PrefService|.
404   // Additionally fires a PREF_CHANGED notification with the top-level
405   // |kExtensionsPref| path set.
406   // TODO(andybons): Switch this to EXTENSION_PREF_CHANGED to be more granular.
407   // TODO(andybons): Use a ScopedUserPrefUpdate to update observers on changes
408   // to the mutable extension dictionary.
409   void SavePrefs();
410 
411   // Checks if kPrefBlacklist is set to true in the DictionaryValue.
412   // Return false if the value is false or kPrefBlacklist does not exist.
413   // This is used to decide if an extension is blacklisted.
414   bool IsBlacklistBitSet(DictionaryValue* ext);
415 
416   // Helper method to acquire the installation time of an extension.
417   // Returns base::Time() if the installation time could not be parsed or
418   // found.
419   base::Time GetInstallTime(const std::string& extension_id) const;
420 
421   // Fix missing preference entries in the extensions that are were introduced
422   // in a later Chrome version.
423   void FixMissingPrefs(const ExtensionIdSet& extension_ids);
424 
425   // Installs the persistent extension preferences into |prefs_|'s extension
426   // pref store.
427   void InitPrefStore();
428 
429   // The pref service specific to this set of extension prefs. Owned by profile.
430   PrefService* prefs_;
431 
432   // Base extensions install directory.
433   FilePath install_directory_;
434 
435   // Weak pointer, owned by Profile.
436   ExtensionPrefValueMap* extension_pref_value_map_;
437 
438   // The URLs of all of the toolstrips.
439   URLList shelf_order_;
440 
441   DISALLOW_COPY_AND_ASSIGN(ExtensionPrefs);
442 };
443 
444 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_PREFS_H_
445