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