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 #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.
    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.
    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