Home | History | Annotate | Download | only in policy
      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/policy/configuration_policy_pref_store.h"
      6 
      7 #include <map>
      8 #include <set>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/command_line.h"
     13 #include "base/lazy_instance.h"
     14 #include "base/logging.h"
     15 #include "base/stl_util-inl.h"
     16 #include "base/string16.h"
     17 #include "base/string_util.h"
     18 #include "base/utf_string_conversions.h"
     19 #include "base/values.h"
     20 #include "chrome/browser/browser_process.h"
     21 #include "chrome/browser/policy/browser_policy_connector.h"
     22 #include "chrome/browser/policy/configuration_policy_provider.h"
     23 #include "chrome/browser/policy/policy_path_parser.h"
     24 #include "chrome/browser/policy/profile_policy_connector.h"
     25 #include "chrome/browser/prefs/pref_value_map.h"
     26 #include "chrome/browser/prefs/proxy_config_dictionary.h"
     27 #include "chrome/browser/profiles/profile.h"
     28 #include "chrome/browser/search_engines/search_terms_data.h"
     29 #include "chrome/browser/search_engines/template_url.h"
     30 #include "chrome/common/pref_names.h"
     31 #include "content/common/notification_service.h"
     32 #include "policy/policy_constants.h"
     33 
     34 namespace policy {
     35 
     36 // Accepts policy settings from a ConfigurationPolicyProvider, converts them
     37 // to preferences and caches the result.
     38 class ConfigurationPolicyPrefKeeper
     39     : private ConfigurationPolicyStoreInterface {
     40  public:
     41   explicit ConfigurationPolicyPrefKeeper(ConfigurationPolicyProvider* provider);
     42   virtual ~ConfigurationPolicyPrefKeeper();
     43 
     44   // Get a preference value.
     45   PrefStore::ReadResult GetValue(const std::string& key,
     46                                  const Value** result) const;
     47 
     48   // Compute the set of preference names that are different in |keeper|. This
     49   // includes preferences that are missing in either one.
     50   void GetDifferingPrefPaths(const ConfigurationPolicyPrefKeeper* other,
     51                              std::vector<std::string>* differing_prefs) const;
     52 
     53  private:
     54   // ConfigurationPolicyStore methods:
     55   virtual void Apply(ConfigurationPolicyType setting, Value* value);
     56 
     57   // Policies that map to a single preference are handled
     58   // by an automated converter. Each one of these policies
     59   // has an entry in |simple_policy_map_| with the following type.
     60   struct PolicyToPreferenceMapEntry {
     61     Value::ValueType value_type;
     62     ConfigurationPolicyType policy_type;
     63     const char* preference_path;  // A DictionaryValue path, not a file path.
     64   };
     65 
     66   // Remove the preferences found in the map from |prefs_|. Returns true if any
     67   // such preferences were found and removed.
     68   bool RemovePreferencesOfMap(const PolicyToPreferenceMapEntry* map,
     69                               int table_size);
     70 
     71   bool ApplyPolicyFromMap(ConfigurationPolicyType policy,
     72                           Value* value,
     73                           const PolicyToPreferenceMapEntry* map,
     74                           int size);
     75 
     76   // Processes proxy-specific policies. Returns true if the specified policy
     77   // is a proxy-related policy. ApplyProxyPolicy assumes the ownership
     78   // of |value| in the case that the policy is proxy-specific.
     79   bool ApplyProxyPolicy(ConfigurationPolicyType policy, Value* value);
     80 
     81   // Handles sync-related policies. Returns true if the policy was handled.
     82   // Assumes ownership of |value| in that case.
     83   bool ApplySyncPolicy(ConfigurationPolicyType policy, Value* value);
     84 
     85   // Handles policies that affect Autofill. Returns true if the policy was
     86   // handled and assumes ownership of |value| in that case.
     87   bool ApplyAutofillPolicy(ConfigurationPolicyType policy, Value* value);
     88 
     89   // Processes download directory policy. Returns true if the specified policy
     90   // is the download directory policy. ApplyDownloadDirPolicy assumes the
     91   // ownership of |value| in the case that the policy is recognized.
     92   bool ApplyDownloadDirPolicy(ConfigurationPolicyType policy, Value* value);
     93 
     94   // Make sure that the |path| if present in |prefs_|.  If not, set it to
     95   // a blank string.
     96   void EnsureStringPrefExists(const std::string& path);
     97 
     98   // If the required entries for default search are specified and valid,
     99   // finalizes the policy-specified configuration by initializing the
    100   // unspecified map entries.  Otherwise wipes all default search related
    101   // map entries from |prefs_|.
    102   void FinalizeDefaultSearchPolicySettings();
    103 
    104   // If the required entries for the proxy settings are specified and valid,
    105   // finalizes the policy-specified configuration by initializing the
    106   // respective values in |prefs_|.
    107   void FinalizeProxyPolicySettings();
    108 
    109   // Returns true if the policy values stored in proxy_* represent a valid proxy
    110   // configuration, including the case in which there is no configuration at
    111   // all.
    112   bool CheckProxySettings();
    113 
    114   // Assumes CheckProxySettings returns true and applies the values stored
    115   // in proxy_*.
    116   void ApplyProxySettings();
    117 
    118   bool HasProxyPolicy(ConfigurationPolicyType policy) const;
    119 
    120   // Temporary cache that stores values until FinalizeProxyPolicySettings()
    121   // is called.
    122   std::map<ConfigurationPolicyType, Value*> proxy_policies_;
    123 
    124   PrefValueMap prefs_;
    125 
    126   static const PolicyToPreferenceMapEntry kSimplePolicyMap[];
    127   static const PolicyToPreferenceMapEntry kDefaultSearchPolicyMap[];
    128 
    129   DISALLOW_COPY_AND_ASSIGN(ConfigurationPolicyPrefKeeper);
    130 };
    131 
    132 const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry
    133     ConfigurationPolicyPrefKeeper::kSimplePolicyMap[] = {
    134   { Value::TYPE_STRING, kPolicyHomepageLocation,  prefs::kHomePage },
    135   { Value::TYPE_BOOLEAN, kPolicyHomepageIsNewTabPage,
    136     prefs::kHomePageIsNewTabPage },
    137   { Value::TYPE_INTEGER, kPolicyRestoreOnStartup,
    138     prefs::kRestoreOnStartup},
    139   { Value::TYPE_LIST, kPolicyRestoreOnStartupURLs,
    140     prefs::kURLsToRestoreOnStartup },
    141   { Value::TYPE_BOOLEAN, kPolicyAlternateErrorPagesEnabled,
    142     prefs::kAlternateErrorPagesEnabled },
    143   { Value::TYPE_BOOLEAN, kPolicySearchSuggestEnabled,
    144     prefs::kSearchSuggestEnabled },
    145   { Value::TYPE_BOOLEAN, kPolicyDnsPrefetchingEnabled,
    146     prefs::kNetworkPredictionEnabled },
    147   { Value::TYPE_BOOLEAN, kPolicyDisableSpdy,
    148     prefs::kDisableSpdy },
    149   { Value::TYPE_LIST, kPolicyDisabledSchemes,
    150     prefs::kDisabledSchemes },
    151   { Value::TYPE_BOOLEAN, kPolicySafeBrowsingEnabled,
    152     prefs::kSafeBrowsingEnabled },
    153   { Value::TYPE_BOOLEAN, kPolicyPasswordManagerEnabled,
    154     prefs::kPasswordManagerEnabled },
    155   { Value::TYPE_BOOLEAN, kPolicyPasswordManagerAllowShowPasswords,
    156     prefs::kPasswordManagerAllowShowPasswords },
    157   { Value::TYPE_BOOLEAN, kPolicyPrintingEnabled,
    158     prefs::kPrintingEnabled },
    159   { Value::TYPE_BOOLEAN, kPolicyMetricsReportingEnabled,
    160     prefs::kMetricsReportingEnabled },
    161   { Value::TYPE_STRING, kPolicyApplicationLocaleValue,
    162     prefs::kApplicationLocale},
    163   { Value::TYPE_LIST, kPolicyExtensionInstallWhitelist,
    164     prefs::kExtensionInstallAllowList},
    165   { Value::TYPE_LIST, kPolicyExtensionInstallBlacklist,
    166     prefs::kExtensionInstallDenyList},
    167   { Value::TYPE_LIST, kPolicyExtensionInstallForcelist,
    168     prefs::kExtensionInstallForceList},
    169   { Value::TYPE_LIST, kPolicyDisabledPlugins,
    170     prefs::kPluginsDisabledPlugins},
    171   { Value::TYPE_LIST, kPolicyDisabledPluginsExceptions,
    172     prefs::kPluginsDisabledPluginsExceptions},
    173   { Value::TYPE_LIST, kPolicyEnabledPlugins,
    174     prefs::kPluginsEnabledPlugins},
    175   { Value::TYPE_BOOLEAN, kPolicyShowHomeButton,
    176     prefs::kShowHomeButton },
    177   { Value::TYPE_BOOLEAN, kPolicyJavascriptEnabled,
    178     prefs::kWebKitJavascriptEnabled },
    179   { Value::TYPE_BOOLEAN, kPolicyIncognitoEnabled,
    180     prefs::kIncognitoEnabled },
    181   { Value::TYPE_BOOLEAN, kPolicySavingBrowserHistoryDisabled,
    182     prefs::kSavingBrowserHistoryDisabled },
    183   { Value::TYPE_BOOLEAN, kPolicyClearSiteDataOnExit,
    184     prefs::kClearSiteDataOnExit },
    185   { Value::TYPE_BOOLEAN, kPolicyDeveloperToolsDisabled,
    186     prefs::kDevToolsDisabled },
    187   { Value::TYPE_BOOLEAN, kPolicyBlockThirdPartyCookies,
    188     prefs::kBlockThirdPartyCookies },
    189   { Value::TYPE_INTEGER, kPolicyDefaultCookiesSetting,
    190     prefs::kManagedDefaultCookiesSetting },
    191   { Value::TYPE_INTEGER, kPolicyDefaultImagesSetting,
    192     prefs::kManagedDefaultImagesSetting },
    193   { Value::TYPE_INTEGER, kPolicyDefaultJavaScriptSetting,
    194     prefs::kManagedDefaultJavaScriptSetting },
    195   { Value::TYPE_INTEGER, kPolicyDefaultPluginsSetting,
    196     prefs::kManagedDefaultPluginsSetting },
    197   { Value::TYPE_INTEGER, kPolicyDefaultPopupsSetting,
    198     prefs::kManagedDefaultPopupsSetting },
    199   { Value::TYPE_LIST, kPolicyCookiesAllowedForUrls,
    200     prefs::kManagedCookiesAllowedForUrls },
    201   { Value::TYPE_LIST, kPolicyCookiesBlockedForUrls,
    202     prefs::kManagedCookiesBlockedForUrls },
    203   { Value::TYPE_LIST, kPolicyCookiesSessionOnlyForUrls,
    204     prefs::kManagedCookiesSessionOnlyForUrls },
    205   { Value::TYPE_LIST, kPolicyImagesAllowedForUrls,
    206     prefs::kManagedImagesAllowedForUrls },
    207   { Value::TYPE_LIST, kPolicyImagesBlockedForUrls,
    208     prefs::kManagedImagesBlockedForUrls },
    209   { Value::TYPE_LIST, kPolicyJavaScriptAllowedForUrls,
    210     prefs::kManagedJavaScriptAllowedForUrls },
    211   { Value::TYPE_LIST, kPolicyJavaScriptBlockedForUrls,
    212     prefs::kManagedJavaScriptBlockedForUrls },
    213   { Value::TYPE_LIST, kPolicyPluginsAllowedForUrls,
    214     prefs::kManagedPluginsAllowedForUrls },
    215   { Value::TYPE_LIST, kPolicyPluginsBlockedForUrls,
    216     prefs::kManagedPluginsBlockedForUrls },
    217   { Value::TYPE_LIST, kPolicyPopupsAllowedForUrls,
    218     prefs::kManagedPopupsAllowedForUrls },
    219   { Value::TYPE_LIST, kPolicyPopupsBlockedForUrls,
    220     prefs::kManagedPopupsBlockedForUrls },
    221   { Value::TYPE_INTEGER, kPolicyDefaultNotificationSetting,
    222     prefs::kDesktopNotificationDefaultContentSetting },
    223   { Value::TYPE_INTEGER, kPolicyDefaultGeolocationSetting,
    224     prefs::kGeolocationDefaultContentSetting },
    225   { Value::TYPE_STRING, kPolicyAuthSchemes,
    226     prefs::kAuthSchemes },
    227   { Value::TYPE_BOOLEAN, kPolicyDisableAuthNegotiateCnameLookup,
    228     prefs::kDisableAuthNegotiateCnameLookup },
    229   { Value::TYPE_BOOLEAN, kPolicyEnableAuthNegotiatePort,
    230     prefs::kEnableAuthNegotiatePort },
    231   { Value::TYPE_STRING, kPolicyAuthServerWhitelist,
    232     prefs::kAuthServerWhitelist },
    233   { Value::TYPE_STRING, kPolicyAuthNegotiateDelegateWhitelist,
    234     prefs::kAuthNegotiateDelegateWhitelist },
    235   { Value::TYPE_STRING, kPolicyGSSAPILibraryName,
    236     prefs::kGSSAPILibraryName },
    237   { Value::TYPE_BOOLEAN, kPolicyDisable3DAPIs,
    238     prefs::kDisable3DAPIs },
    239   { Value::TYPE_BOOLEAN, kPolicyDisablePluginFinder,
    240     prefs::kDisablePluginFinder },
    241   { Value::TYPE_INTEGER, kPolicyPolicyRefreshRate,
    242     prefs::kPolicyRefreshRate },
    243   { Value::TYPE_BOOLEAN, kPolicyInstantEnabled, prefs::kInstantEnabled },
    244   { Value::TYPE_BOOLEAN, kPolicyDefaultBrowserSettingEnabled,
    245     prefs::kDefaultBrowserSettingEnabled },
    246   { Value::TYPE_BOOLEAN, kPolicyCloudPrintProxyEnabled,
    247     prefs::kCloudPrintProxyEnabled },
    248   { Value::TYPE_BOOLEAN, kPolicyTranslateEnabled, prefs::kEnableTranslate },
    249   { Value::TYPE_BOOLEAN, kPolicyBookmarkBarEnabled, prefs::kEnableBookmarkBar },
    250   { Value::TYPE_BOOLEAN, kPolicyAllowOutdatedPlugins,
    251     prefs::kPluginsAllowOutdated },
    252   { Value::TYPE_BOOLEAN, kPolicyEditBookmarksEnabled,
    253     prefs::kEditBookmarksEnabled },
    254   { Value::TYPE_BOOLEAN, kPolicyAllowFileSelectionDialogs,
    255     prefs::kAllowFileSelectionDialogs },
    256 
    257 #if defined(OS_CHROMEOS)
    258   { Value::TYPE_BOOLEAN, kPolicyChromeOsLockOnIdleSuspend,
    259     prefs::kEnableScreenLock },
    260 #endif
    261 };
    262 
    263 const ConfigurationPolicyPrefKeeper::PolicyToPreferenceMapEntry
    264     ConfigurationPolicyPrefKeeper::kDefaultSearchPolicyMap[] = {
    265   { Value::TYPE_BOOLEAN, kPolicyDefaultSearchProviderEnabled,
    266     prefs::kDefaultSearchProviderEnabled },
    267   { Value::TYPE_STRING, kPolicyDefaultSearchProviderName,
    268     prefs::kDefaultSearchProviderName },
    269   { Value::TYPE_STRING, kPolicyDefaultSearchProviderKeyword,
    270     prefs::kDefaultSearchProviderKeyword },
    271   { Value::TYPE_STRING, kPolicyDefaultSearchProviderSearchURL,
    272     prefs::kDefaultSearchProviderSearchURL },
    273   { Value::TYPE_STRING, kPolicyDefaultSearchProviderSuggestURL,
    274     prefs::kDefaultSearchProviderSuggestURL },
    275   { Value::TYPE_STRING, kPolicyDefaultSearchProviderIconURL,
    276     prefs::kDefaultSearchProviderIconURL },
    277   { Value::TYPE_STRING, kPolicyDefaultSearchProviderEncodings,
    278     prefs::kDefaultSearchProviderEncodings },
    279 };
    280 
    281 ConfigurationPolicyPrefKeeper::ConfigurationPolicyPrefKeeper(
    282     ConfigurationPolicyProvider* provider) {
    283   if (!provider->Provide(this))
    284     LOG(WARNING) << "Failed to get policy from provider.";
    285   FinalizeProxyPolicySettings();
    286   FinalizeDefaultSearchPolicySettings();
    287 }
    288 
    289 ConfigurationPolicyPrefKeeper::~ConfigurationPolicyPrefKeeper() {
    290   DCHECK(proxy_policies_.empty());
    291 }
    292 
    293 PrefStore::ReadResult
    294 ConfigurationPolicyPrefKeeper::GetValue(const std::string& key,
    295                                         const Value** result) const {
    296   const Value* stored_value = NULL;
    297   if (!prefs_.GetValue(key, &stored_value))
    298     return PrefStore::READ_NO_VALUE;
    299 
    300   // Check whether there's a default value, which indicates READ_USE_DEFAULT
    301   // should be returned.
    302   if (stored_value->IsType(Value::TYPE_NULL))
    303     return PrefStore::READ_USE_DEFAULT;
    304 
    305   *result = stored_value;
    306   return PrefStore::READ_OK;
    307 }
    308 
    309 void ConfigurationPolicyPrefKeeper::GetDifferingPrefPaths(
    310     const ConfigurationPolicyPrefKeeper* other,
    311     std::vector<std::string>* differing_prefs) const {
    312   prefs_.GetDifferingKeys(&other->prefs_, differing_prefs);
    313 }
    314 
    315 void ConfigurationPolicyPrefKeeper::Apply(ConfigurationPolicyType policy,
    316                                           Value* value) {
    317   if (ApplyProxyPolicy(policy, value))
    318     return;
    319 
    320   if (ApplySyncPolicy(policy, value))
    321     return;
    322 
    323   if (ApplyAutofillPolicy(policy, value))
    324     return;
    325 
    326   if (ApplyDownloadDirPolicy(policy, value))
    327     return;
    328 
    329   if (ApplyPolicyFromMap(policy, value, kDefaultSearchPolicyMap,
    330                          arraysize(kDefaultSearchPolicyMap)))
    331     return;
    332 
    333   if (ApplyPolicyFromMap(policy, value, kSimplePolicyMap,
    334                          arraysize(kSimplePolicyMap)))
    335     return;
    336 
    337   // Other policy implementations go here.
    338   NOTIMPLEMENTED();
    339   delete value;
    340 }
    341 
    342 bool ConfigurationPolicyPrefKeeper::RemovePreferencesOfMap(
    343     const PolicyToPreferenceMapEntry* map, int table_size) {
    344   bool found_any = false;
    345   for (int i = 0; i < table_size; ++i) {
    346     if (prefs_.RemoveValue(map[i].preference_path))
    347       found_any = true;
    348   }
    349   return found_any;
    350 }
    351 
    352 bool ConfigurationPolicyPrefKeeper::ApplyPolicyFromMap(
    353     ConfigurationPolicyType policy,
    354     Value* value,
    355     const PolicyToPreferenceMapEntry* map,
    356     int size) {
    357   for (int current = 0; current < size; ++current) {
    358     if (map[current].policy_type == policy) {
    359       DCHECK_EQ(map[current].value_type, value->GetType())
    360           << "mismatch in provided and expected policy value for preferences"
    361           << map[current].preference_path << ". expected = "
    362           << map[current].value_type << ", actual = "<< value->GetType();
    363       prefs_.SetValue(map[current].preference_path, value);
    364       return true;
    365     }
    366   }
    367   return false;
    368 }
    369 
    370 bool ConfigurationPolicyPrefKeeper::ApplyProxyPolicy(
    371     ConfigurationPolicyType policy,
    372     Value* value) {
    373   // We only collect the values until we have sufficient information when
    374   // FinalizeProxyPolicySettings() is called to determine whether the presented
    375   // values were correct and apply them in that case.
    376   if (policy == kPolicyProxyMode ||
    377       policy == kPolicyProxyServerMode ||
    378       policy == kPolicyProxyServer ||
    379       policy == kPolicyProxyPacUrl ||
    380       policy == kPolicyProxyBypassList) {
    381     delete proxy_policies_[policy];
    382     proxy_policies_[policy] = value;
    383     return true;
    384   }
    385   // We are not interested in this policy.
    386   return false;
    387 }
    388 
    389 bool ConfigurationPolicyPrefKeeper::ApplySyncPolicy(
    390     ConfigurationPolicyType policy, Value* value) {
    391   if (policy == kPolicySyncDisabled) {
    392     bool disable_sync;
    393     if (value->GetAsBoolean(&disable_sync) && disable_sync)
    394       prefs_.SetValue(prefs::kSyncManaged, value);
    395     else
    396       delete value;
    397     return true;
    398   }
    399   return false;
    400 }
    401 
    402 bool ConfigurationPolicyPrefKeeper::ApplyAutofillPolicy(
    403     ConfigurationPolicyType policy, Value* value) {
    404   if (policy == kPolicyAutoFillEnabled) {
    405     bool auto_fill_enabled;
    406     if (value->GetAsBoolean(&auto_fill_enabled) && !auto_fill_enabled)
    407       prefs_.SetValue(prefs::kAutofillEnabled,
    408                        Value::CreateBooleanValue(false));
    409     delete value;
    410     return true;
    411   }
    412   return false;
    413 }
    414 
    415 bool ConfigurationPolicyPrefKeeper::ApplyDownloadDirPolicy(
    416     ConfigurationPolicyType policy,
    417     Value* value) {
    418   // Replace the policy string which might contain some user variables to an
    419   // expanded string.
    420   if (policy == kPolicyDownloadDirectory) {
    421     FilePath::StringType string_value;
    422     bool result = value->GetAsString(&string_value);
    423     DCHECK(result);
    424     FilePath::StringType expanded_value =
    425         policy::path_parser::ExpandPathVariables(string_value);
    426     prefs_.SetValue(prefs::kDownloadDefaultDirectory,
    427                     Value::CreateStringValue(expanded_value));
    428     prefs_.SetValue(prefs::kPromptForDownload,
    429                     Value::CreateBooleanValue(false));
    430     delete value;
    431     return true;
    432   }
    433   // We are not interested in this policy.
    434   return false;
    435 }
    436 
    437 void ConfigurationPolicyPrefKeeper::EnsureStringPrefExists(
    438     const std::string& path) {
    439   std::string value;
    440   if (!prefs_.GetString(path, &value))
    441     prefs_.SetString(path, value);
    442 }
    443 
    444 namespace {
    445 
    446 // Implementation of SearchTermsData just for validation.
    447 class SearchTermsDataForValidation : public SearchTermsData {
    448  public:
    449   SearchTermsDataForValidation() {}
    450 
    451   // Implementation of SearchTermsData.
    452   virtual std::string GoogleBaseURLValue() const {
    453     return "http://www.google.com/";
    454   }
    455   virtual std::string GetApplicationLocale() const {
    456     return "en";
    457   }
    458 #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
    459   virtual string16 GetRlzParameterValue() const {
    460     return string16();
    461   }
    462 #endif
    463  private:
    464   DISALLOW_COPY_AND_ASSIGN(SearchTermsDataForValidation);
    465 };
    466 
    467 }  // namespace
    468 
    469 void ConfigurationPolicyPrefKeeper::FinalizeDefaultSearchPolicySettings() {
    470   bool enabled = true;
    471   if (prefs_.GetBoolean(prefs::kDefaultSearchProviderEnabled, &enabled) &&
    472       !enabled) {
    473     // If default search is disabled, we ignore the other fields.
    474     prefs_.SetString(prefs::kDefaultSearchProviderName, std::string());
    475     prefs_.SetString(prefs::kDefaultSearchProviderSearchURL, std::string());
    476     prefs_.SetString(prefs::kDefaultSearchProviderSuggestURL, std::string());
    477     prefs_.SetString(prefs::kDefaultSearchProviderIconURL, std::string());
    478     prefs_.SetString(prefs::kDefaultSearchProviderEncodings, std::string());
    479     prefs_.SetString(prefs::kDefaultSearchProviderKeyword, std::string());
    480     prefs_.SetString(prefs::kDefaultSearchProviderInstantURL, std::string());
    481     return;
    482   }
    483   std::string search_url;
    484   // The search URL is required.
    485   if (prefs_.GetString(prefs::kDefaultSearchProviderSearchURL, &search_url) &&
    486       !search_url.empty()) {
    487     SearchTermsDataForValidation search_terms_data;
    488     const TemplateURLRef search_url_ref(search_url, 0, 0);
    489     // It must support replacement (which implies it is valid).
    490     if (search_url_ref.SupportsReplacementUsingTermsData(search_terms_data)) {
    491       // The other entries are optional.  Just make sure that they are all
    492       // specified via policy, so that we don't use regular prefs.
    493       EnsureStringPrefExists(prefs::kDefaultSearchProviderSuggestURL);
    494       EnsureStringPrefExists(prefs::kDefaultSearchProviderIconURL);
    495       EnsureStringPrefExists(prefs::kDefaultSearchProviderEncodings);
    496       EnsureStringPrefExists(prefs::kDefaultSearchProviderKeyword);
    497       EnsureStringPrefExists(prefs::kDefaultSearchProviderInstantURL);
    498 
    499       // For the name, default to the host if not specified.
    500       std::string name;
    501       if (!prefs_.GetString(prefs::kDefaultSearchProviderName, &name) ||
    502           name.empty())
    503         prefs_.SetString(prefs::kDefaultSearchProviderName,
    504                           GURL(search_url).host());
    505 
    506       // And clear the IDs since these are not specified via policy.
    507       prefs_.SetString(prefs::kDefaultSearchProviderID, std::string());
    508       prefs_.SetString(prefs::kDefaultSearchProviderPrepopulateID,
    509                         std::string());
    510       return;
    511     }
    512   }
    513   // Required entries are not there.  Remove any related entries.
    514   RemovePreferencesOfMap(kDefaultSearchPolicyMap,
    515                          arraysize(kDefaultSearchPolicyMap));
    516 }
    517 
    518 void ConfigurationPolicyPrefKeeper::FinalizeProxyPolicySettings() {
    519   if (CheckProxySettings())
    520     ApplyProxySettings();
    521 
    522   STLDeleteContainerPairSecondPointers(proxy_policies_.begin(),
    523                                        proxy_policies_.end());
    524   proxy_policies_.clear();
    525 }
    526 
    527 bool ConfigurationPolicyPrefKeeper::CheckProxySettings() {
    528   bool mode = HasProxyPolicy(kPolicyProxyMode);
    529   bool server_mode = HasProxyPolicy(kPolicyProxyServerMode);  // deprecated
    530   bool server = HasProxyPolicy(kPolicyProxyServer);
    531   bool pac_url = HasProxyPolicy(kPolicyProxyPacUrl);
    532   bool bypass_list = HasProxyPolicy(kPolicyProxyBypassList);
    533 
    534   if ((server || pac_url || bypass_list) && !(mode || server_mode)) {
    535     LOG(WARNING) << "A centrally-administered policy defines proxy setting"
    536                  << " details without setting a proxy mode.";
    537     return false;
    538   }
    539 
    540   // If there's a server mode, convert it into a mode.
    541   std::string mode_value;
    542   if (mode) {
    543     if (server_mode)
    544       LOG(WARNING) << "Both ProxyMode and ProxyServerMode policies defined, "
    545                    << "ignoring ProxyMode.";
    546     if (!proxy_policies_[kPolicyProxyMode]->GetAsString(&mode_value)) {
    547       LOG(WARNING) << "Invalid ProxyMode value.";
    548       return false;
    549     }
    550   } else if (server_mode) {
    551     int server_mode_value;
    552     if (!proxy_policies_[kPolicyProxyServerMode]->GetAsInteger(
    553         &server_mode_value)) {
    554       LOG(WARNING) << "Invalid ProxyServerMode value.";
    555       return false;
    556     }
    557 
    558     switch (server_mode_value) {
    559       case kPolicyNoProxyServerMode:
    560         mode_value = ProxyPrefs::kDirectProxyModeName;
    561         break;
    562       case kPolicyAutoDetectProxyServerMode:
    563         mode_value = ProxyPrefs::kAutoDetectProxyModeName;
    564         break;
    565       case kPolicyManuallyConfiguredProxyServerMode:
    566         if (server && pac_url) {
    567           LOG(WARNING) << "A centrally-administered policy dictates that"
    568                        << " both fixed proxy servers and a .pac url. should"
    569                        << " be used for proxy configuration.";
    570           return false;
    571         }
    572         if (!server && !pac_url) {
    573           LOG(WARNING) << "A centrally-administered policy dictates that the"
    574                        << " proxy settings should use either fixed proxy"
    575                        << " servers or a .pac url, but specifies neither.";
    576           return false;
    577         }
    578         if (pac_url)
    579           mode_value = ProxyPrefs::kPacScriptProxyModeName;
    580         else
    581           mode_value = ProxyPrefs::kFixedServersProxyModeName;
    582         break;
    583       case kPolicyUseSystemProxyServerMode:
    584         mode_value = ProxyPrefs::kSystemProxyModeName;
    585         break;
    586       default:
    587         LOG(WARNING) << "Invalid proxy mode " << server_mode_value;
    588         return false;
    589     }
    590   }
    591 
    592   // If neither ProxyMode nor ProxyServerMode are specified, mode_value will be
    593   // empty and the proxy shouldn't be configured at all.
    594   if (mode_value.empty())
    595     return true;
    596 
    597   if (mode_value == ProxyPrefs::kDirectProxyModeName) {
    598     if (server || pac_url || bypass_list) {
    599       LOG(WARNING) << "A centrally-administered policy disables the use of"
    600                    << " a proxy but also specifies an explicit proxy"
    601                    << " configuration.";
    602       return false;
    603     }
    604   } else if (mode_value == ProxyPrefs::kAutoDetectProxyModeName) {
    605     if (server || bypass_list || pac_url) {
    606       LOG(WARNING) << "A centrally-administered policy dictates that a proxy"
    607                    << " shall be auto configured but specifies fixed proxy"
    608                    << " servers, a by-pass list or a .pac script URL.";
    609       return false;
    610     }
    611   } else if (mode_value == ProxyPrefs::kPacScriptProxyModeName) {
    612     if (server || bypass_list) {
    613       LOG(WARNING) << "A centrally-administered policy dictates that a .pac"
    614                    << " script URL should be used for proxy configuration but"
    615                    << " also specifies policies required only for fixed"
    616                    << " proxy servers.";
    617       return false;
    618     }
    619   } else if (mode_value == ProxyPrefs::kFixedServersProxyModeName) {
    620     if (pac_url) {
    621       LOG(WARNING) << "A centrally-administered policy dictates that"
    622                    << " fixed proxy servers should be used but also"
    623                    << " specifies a .pac script URL.";
    624       return false;
    625     }
    626   } else if (mode_value == ProxyPrefs::kSystemProxyModeName) {
    627     if (server || pac_url || bypass_list) {
    628       LOG(WARNING) << "A centrally-administered policy dictates that the"
    629                    << " system proxy settings should be used but also "
    630                    << " specifies an explicit proxy configuration.";
    631       return false;
    632     }
    633   } else {
    634     LOG(WARNING) << "Invalid proxy mode " << mode_value;
    635     return false;
    636   }
    637   return true;
    638 }
    639 
    640 void ConfigurationPolicyPrefKeeper::ApplyProxySettings() {
    641   ProxyPrefs::ProxyMode mode;
    642   if (HasProxyPolicy(kPolicyProxyMode)) {
    643     std::string string_mode;
    644     CHECK(proxy_policies_[kPolicyProxyMode]->GetAsString(&string_mode));
    645     if (!ProxyPrefs::StringToProxyMode(string_mode, &mode)) {
    646       LOG(WARNING) << "A centrally-administered policy specifies a value for"
    647                    << "the ProxyMode policy that isn't recognized.";
    648       return;
    649     }
    650   } else if (HasProxyPolicy(kPolicyProxyServerMode)) {
    651     int int_mode = 0;
    652     CHECK(proxy_policies_[kPolicyProxyServerMode]->GetAsInteger(&int_mode));
    653     switch (int_mode) {
    654       case kPolicyNoProxyServerMode:
    655         mode = ProxyPrefs::MODE_DIRECT;
    656         break;
    657       case kPolicyAutoDetectProxyServerMode:
    658         mode = ProxyPrefs::MODE_AUTO_DETECT;
    659         break;
    660       case kPolicyManuallyConfiguredProxyServerMode:
    661         mode = ProxyPrefs::MODE_FIXED_SERVERS;
    662         if (HasProxyPolicy(kPolicyProxyPacUrl))
    663           mode = ProxyPrefs::MODE_PAC_SCRIPT;
    664         break;
    665       case kPolicyUseSystemProxyServerMode:
    666         mode = ProxyPrefs::MODE_SYSTEM;
    667         break;
    668       default:
    669         mode = ProxyPrefs::MODE_DIRECT;
    670         NOTREACHED();
    671     }
    672   } else {
    673     return;
    674   }
    675   switch (mode) {
    676     case ProxyPrefs::MODE_DIRECT:
    677       prefs_.SetValue(prefs::kProxy, ProxyConfigDictionary::CreateDirect());
    678       break;
    679     case ProxyPrefs::MODE_AUTO_DETECT:
    680       prefs_.SetValue(prefs::kProxy, ProxyConfigDictionary::CreateAutoDetect());
    681       break;
    682     case ProxyPrefs::MODE_PAC_SCRIPT: {
    683       if (!HasProxyPolicy(kPolicyProxyPacUrl)) {
    684         LOG(WARNING) << "A centrally-administered policy specifies to use a "
    685                      << "PAC script, but doesn't supply the PAC script URL.";
    686         return;
    687       }
    688       std::string pac_url;
    689       proxy_policies_[kPolicyProxyPacUrl]->GetAsString(&pac_url);
    690       prefs_.SetValue(prefs::kProxy,
    691                       ProxyConfigDictionary::CreatePacScript(pac_url));
    692       break;
    693     }
    694     case ProxyPrefs::MODE_FIXED_SERVERS: {
    695       if (!HasProxyPolicy(kPolicyProxyServer)) {
    696         LOG(WARNING) << "A centrally-administered policy specifies to use a "
    697                      << "fixed server, but doesn't supply the server address.";
    698         return;
    699       }
    700       std::string proxy_server;
    701       proxy_policies_[kPolicyProxyServer]->GetAsString(&proxy_server);
    702       std::string bypass_list;
    703       if (HasProxyPolicy(kPolicyProxyBypassList))
    704         proxy_policies_[kPolicyProxyBypassList]->GetAsString(&bypass_list);
    705       prefs_.SetValue(prefs::kProxy,
    706                       ProxyConfigDictionary::CreateFixedServers(proxy_server,
    707                                                                 bypass_list));
    708       break;
    709     }
    710     case ProxyPrefs::MODE_SYSTEM:
    711       prefs_.SetValue(prefs::kProxy,
    712                       ProxyConfigDictionary::CreateSystem());
    713       break;
    714     case ProxyPrefs::kModeCount:
    715       NOTREACHED();
    716   }
    717 }
    718 
    719 bool ConfigurationPolicyPrefKeeper::HasProxyPolicy(
    720     ConfigurationPolicyType policy) const {
    721   std::map<ConfigurationPolicyType, Value*>::const_iterator iter;
    722   iter = proxy_policies_.find(policy);
    723   std::string tmp;
    724   if (iter == proxy_policies_.end() ||
    725       !iter->second ||
    726       iter->second->IsType(Value::TYPE_NULL) ||
    727       (iter->second->IsType(Value::TYPE_STRING) &&
    728        iter->second->GetAsString(&tmp) &&
    729        tmp.empty())) {
    730     return false;
    731   }
    732   return true;
    733 }
    734 
    735 ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore(
    736     ConfigurationPolicyProvider* provider)
    737     : provider_(provider),
    738       initialization_complete_(false) {
    739   if (provider_) {
    740     // Read initial policy.
    741     policy_keeper_.reset(new ConfigurationPolicyPrefKeeper(provider));
    742     registrar_.Init(provider_, this);
    743     initialization_complete_ = provider->IsInitializationComplete();
    744   } else {
    745     initialization_complete_ = true;
    746   }
    747 }
    748 
    749 ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {
    750 }
    751 
    752 void ConfigurationPolicyPrefStore::AddObserver(PrefStore::Observer* observer) {
    753   observers_.AddObserver(observer);
    754 }
    755 
    756 void ConfigurationPolicyPrefStore::RemoveObserver(
    757     PrefStore::Observer* observer) {
    758   observers_.RemoveObserver(observer);
    759 }
    760 
    761 bool ConfigurationPolicyPrefStore::IsInitializationComplete() const {
    762   return initialization_complete_;
    763 }
    764 
    765 PrefStore::ReadResult
    766 ConfigurationPolicyPrefStore::GetValue(const std::string& key,
    767                                        const Value** value) const {
    768   if (policy_keeper_.get())
    769     return policy_keeper_->GetValue(key, value);
    770 
    771   return PrefStore::READ_NO_VALUE;
    772 }
    773 
    774 void ConfigurationPolicyPrefStore::OnUpdatePolicy() {
    775   Refresh();
    776 }
    777 
    778 void ConfigurationPolicyPrefStore::OnProviderGoingAway() {
    779   provider_ = NULL;
    780 }
    781 
    782 // static
    783 ConfigurationPolicyPrefStore*
    784 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore() {
    785   BrowserPolicyConnector* connector =
    786       g_browser_process->browser_policy_connector();
    787   return new ConfigurationPolicyPrefStore(
    788       connector->GetManagedPlatformProvider());
    789 }
    790 
    791 // static
    792 ConfigurationPolicyPrefStore*
    793 ConfigurationPolicyPrefStore::CreateManagedCloudPolicyPrefStore(
    794     Profile* profile) {
    795   ConfigurationPolicyProvider* provider = NULL;
    796   if (profile) {
    797     // For user policy, return the profile's policy provider.
    798     provider = profile->GetPolicyConnector()->GetManagedCloudProvider();
    799   } else {
    800     // For device policy, return the provider of the browser process.
    801     BrowserPolicyConnector* connector =
    802         g_browser_process->browser_policy_connector();
    803     provider = connector->GetManagedCloudProvider();
    804   }
    805   return new ConfigurationPolicyPrefStore(provider);
    806 }
    807 
    808 // static
    809 ConfigurationPolicyPrefStore*
    810 ConfigurationPolicyPrefStore::CreateRecommendedPlatformPolicyPrefStore() {
    811   BrowserPolicyConnector* connector =
    812       g_browser_process->browser_policy_connector();
    813   return new ConfigurationPolicyPrefStore(
    814       connector->GetRecommendedPlatformProvider());
    815 }
    816 
    817 // static
    818 ConfigurationPolicyPrefStore*
    819 ConfigurationPolicyPrefStore::CreateRecommendedCloudPolicyPrefStore(
    820     Profile* profile) {
    821   ConfigurationPolicyProvider* provider = NULL;
    822   if (profile) {
    823     // For user policy, return the profile's policy provider.
    824     provider = profile->GetPolicyConnector()->GetRecommendedCloudProvider();
    825   } else {
    826     // For device policy, return the provider of the browser process.
    827     BrowserPolicyConnector* connector =
    828         g_browser_process->browser_policy_connector();
    829     provider = connector->GetRecommendedCloudProvider();
    830   }
    831   return new ConfigurationPolicyPrefStore(provider);
    832 }
    833 
    834 /* static */
    835 const ConfigurationPolicyProvider::PolicyDefinitionList*
    836 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList() {
    837   static ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[] = {
    838     { kPolicyHomepageLocation, Value::TYPE_STRING, key::kHomepageLocation },
    839     { kPolicyHomepageIsNewTabPage, Value::TYPE_BOOLEAN,
    840       key::kHomepageIsNewTabPage },
    841     { kPolicyRestoreOnStartup, Value::TYPE_INTEGER, key::kRestoreOnStartup },
    842     { kPolicyRestoreOnStartupURLs, Value::TYPE_LIST,
    843       key::kRestoreOnStartupURLs },
    844     { kPolicyDefaultSearchProviderEnabled, Value::TYPE_BOOLEAN,
    845       key::kDefaultSearchProviderEnabled },
    846     { kPolicyDefaultSearchProviderName, Value::TYPE_STRING,
    847       key::kDefaultSearchProviderName },
    848     { kPolicyDefaultSearchProviderKeyword, Value::TYPE_STRING,
    849       key::kDefaultSearchProviderKeyword },
    850     { kPolicyDefaultSearchProviderSearchURL, Value::TYPE_STRING,
    851       key::kDefaultSearchProviderSearchURL },
    852     { kPolicyDefaultSearchProviderSuggestURL, Value::TYPE_STRING,
    853       key::kDefaultSearchProviderSuggestURL },
    854     { kPolicyDefaultSearchProviderInstantURL, Value::TYPE_STRING,
    855       key::kDefaultSearchProviderInstantURL },
    856     { kPolicyDefaultSearchProviderIconURL, Value::TYPE_STRING,
    857       key::kDefaultSearchProviderIconURL },
    858     { kPolicyDefaultSearchProviderEncodings, Value::TYPE_STRING,
    859       key::kDefaultSearchProviderEncodings },
    860     { kPolicyProxyMode, Value::TYPE_STRING, key::kProxyMode },
    861     { kPolicyProxyServerMode, Value::TYPE_INTEGER, key::kProxyServerMode },
    862     { kPolicyProxyServer, Value::TYPE_STRING, key::kProxyServer },
    863     { kPolicyProxyPacUrl, Value::TYPE_STRING, key::kProxyPacUrl },
    864     { kPolicyProxyBypassList, Value::TYPE_STRING, key::kProxyBypassList },
    865     { kPolicyAlternateErrorPagesEnabled, Value::TYPE_BOOLEAN,
    866       key::kAlternateErrorPagesEnabled },
    867     { kPolicySearchSuggestEnabled, Value::TYPE_BOOLEAN,
    868       key::kSearchSuggestEnabled },
    869     { kPolicyDnsPrefetchingEnabled, Value::TYPE_BOOLEAN,
    870       key::kDnsPrefetchingEnabled },
    871     { kPolicyDisableSpdy, Value::TYPE_BOOLEAN, key::kDisableSpdy },
    872     { kPolicyDisabledSchemes, Value::TYPE_LIST, key::kDisabledSchemes },
    873     { kPolicySafeBrowsingEnabled, Value::TYPE_BOOLEAN,
    874       key::kSafeBrowsingEnabled },
    875     { kPolicyMetricsReportingEnabled, Value::TYPE_BOOLEAN,
    876       key::kMetricsReportingEnabled },
    877     { kPolicyPasswordManagerEnabled, Value::TYPE_BOOLEAN,
    878       key::kPasswordManagerEnabled },
    879     { kPolicyPasswordManagerAllowShowPasswords, Value::TYPE_BOOLEAN,
    880       key::kPasswordManagerAllowShowPasswords },
    881     { kPolicyAutoFillEnabled, Value::TYPE_BOOLEAN, key::kAutoFillEnabled },
    882     { kPolicyDisabledPlugins, Value::TYPE_LIST, key::kDisabledPlugins },
    883     { kPolicyDisabledPluginsExceptions, Value::TYPE_LIST,
    884       key::kDisabledPluginsExceptions },
    885     { kPolicyEnabledPlugins, Value::TYPE_LIST, key::kEnabledPlugins },
    886     { kPolicyApplicationLocaleValue, Value::TYPE_STRING,
    887       key::kApplicationLocaleValue },
    888     { kPolicySyncDisabled, Value::TYPE_BOOLEAN, key::kSyncDisabled },
    889     { kPolicyExtensionInstallWhitelist, Value::TYPE_LIST,
    890       key::kExtensionInstallWhitelist },
    891     { kPolicyExtensionInstallBlacklist, Value::TYPE_LIST,
    892       key::kExtensionInstallBlacklist },
    893     { kPolicyExtensionInstallForcelist, Value::TYPE_LIST,
    894       key::kExtensionInstallForcelist },
    895     { kPolicyShowHomeButton, Value::TYPE_BOOLEAN, key::kShowHomeButton },
    896     { kPolicyPrintingEnabled, Value::TYPE_BOOLEAN, key::kPrintingEnabled },
    897     { kPolicyJavascriptEnabled, Value::TYPE_BOOLEAN, key::kJavascriptEnabled },
    898     { kPolicyIncognitoEnabled, Value::TYPE_BOOLEAN, key::kIncognitoEnabled },
    899     { kPolicySavingBrowserHistoryDisabled, Value::TYPE_BOOLEAN,
    900       key::kSavingBrowserHistoryDisabled },
    901     { kPolicyClearSiteDataOnExit, Value::TYPE_BOOLEAN,
    902       key::kClearSiteDataOnExit },
    903     { kPolicyDeveloperToolsDisabled, Value::TYPE_BOOLEAN,
    904       key::kDeveloperToolsDisabled },
    905     { kPolicyBlockThirdPartyCookies, Value::TYPE_BOOLEAN,
    906       key::kBlockThirdPartyCookies },
    907     { kPolicyDefaultCookiesSetting, Value::TYPE_INTEGER,
    908       key::kDefaultCookiesSetting },
    909     { kPolicyDefaultImagesSetting, Value::TYPE_INTEGER,
    910       key::kDefaultImagesSetting },
    911     { kPolicyDefaultJavaScriptSetting, Value::TYPE_INTEGER,
    912       key::kDefaultJavaScriptSetting },
    913     { kPolicyDefaultPluginsSetting, Value::TYPE_INTEGER,
    914       key::kDefaultPluginsSetting },
    915     { kPolicyDefaultPopupsSetting, Value::TYPE_INTEGER,
    916       key::kDefaultPopupsSetting },
    917     { kPolicyDefaultNotificationSetting, Value::TYPE_INTEGER,
    918       key::kDefaultNotificationSetting },
    919     { kPolicyDefaultGeolocationSetting, Value::TYPE_INTEGER,
    920       key::kDefaultGeolocationSetting },
    921     { kPolicyCookiesAllowedForUrls, Value::TYPE_LIST,
    922       key::kCookiesAllowedForUrls },
    923     { kPolicyCookiesBlockedForUrls, Value::TYPE_LIST,
    924       key::kCookiesBlockedForUrls },
    925     { kPolicyCookiesSessionOnlyForUrls, Value::TYPE_LIST,
    926       key::kCookiesSessionOnlyForUrls },
    927     { kPolicyImagesAllowedForUrls, Value::TYPE_LIST,
    928       key::kImagesAllowedForUrls },
    929     { kPolicyImagesBlockedForUrls, Value::TYPE_LIST,
    930       key::kImagesBlockedForUrls },
    931     { kPolicyJavaScriptAllowedForUrls, Value::TYPE_LIST,
    932       key::kJavaScriptAllowedForUrls },
    933     { kPolicyJavaScriptBlockedForUrls, Value::TYPE_LIST,
    934       key::kJavaScriptBlockedForUrls },
    935     { kPolicyPluginsAllowedForUrls, Value::TYPE_LIST,
    936       key::kPluginsAllowedForUrls },
    937     { kPolicyPluginsBlockedForUrls, Value::TYPE_LIST,
    938       key::kPluginsBlockedForUrls },
    939     { kPolicyPopupsAllowedForUrls, Value::TYPE_LIST,
    940       key::kPopupsAllowedForUrls },
    941     { kPolicyPopupsBlockedForUrls, Value::TYPE_LIST,
    942       key::kPopupsBlockedForUrls },
    943     { kPolicyAuthSchemes, Value::TYPE_STRING, key::kAuthSchemes },
    944     { kPolicyDisableAuthNegotiateCnameLookup, Value::TYPE_BOOLEAN,
    945       key::kDisableAuthNegotiateCnameLookup },
    946     { kPolicyEnableAuthNegotiatePort, Value::TYPE_BOOLEAN,
    947       key::kEnableAuthNegotiatePort },
    948     { kPolicyAuthServerWhitelist, Value::TYPE_STRING,
    949       key::kAuthServerWhitelist },
    950     { kPolicyAuthNegotiateDelegateWhitelist, Value::TYPE_STRING,
    951       key::kAuthNegotiateDelegateWhitelist },
    952     { kPolicyGSSAPILibraryName, Value::TYPE_STRING,
    953       key::kGSSAPILibraryName },
    954     { kPolicyDisable3DAPIs, Value::TYPE_BOOLEAN,
    955       key::kDisable3DAPIs },
    956     { kPolicyDisablePluginFinder, Value::TYPE_BOOLEAN,
    957       key::kDisablePluginFinder },
    958     { kPolicyPolicyRefreshRate, Value::TYPE_INTEGER,
    959       key::kPolicyRefreshRate },
    960     { kPolicyInstantEnabled, Value::TYPE_BOOLEAN, key::kInstantEnabled },
    961     { kPolicyDefaultBrowserSettingEnabled, Value::TYPE_BOOLEAN,
    962       key::kDefaultBrowserSettingEnabled },
    963     { kPolicyCloudPrintProxyEnabled, Value::TYPE_BOOLEAN,
    964       key::kCloudPrintProxyEnabled },
    965     { kPolicyDownloadDirectory, Value::TYPE_STRING,
    966       key::kDownloadDirectory },
    967     { kPolicyTranslateEnabled, Value::TYPE_BOOLEAN, key::kTranslateEnabled },
    968     { kPolicyAllowOutdatedPlugins, Value::TYPE_BOOLEAN,
    969       key::kAllowOutdatedPlugins },
    970     { kPolicyBookmarkBarEnabled, Value::TYPE_BOOLEAN,
    971       key::kBookmarkBarEnabled },
    972     { kPolicyEditBookmarksEnabled, Value::TYPE_BOOLEAN,
    973       key::kEditBookmarksEnabled },
    974     { kPolicyAllowFileSelectionDialogs, Value::TYPE_BOOLEAN,
    975       key::kAllowFileSelectionDialogs },
    976 
    977 #if defined(OS_CHROMEOS)
    978     { kPolicyChromeOsLockOnIdleSuspend, Value::TYPE_BOOLEAN,
    979       key::kChromeOsLockOnIdleSuspend },
    980 #endif
    981   };
    982 
    983   static ConfigurationPolicyProvider::PolicyDefinitionList policy_list = {
    984     entries,
    985     entries + arraysize(entries),
    986   };
    987   return &policy_list;
    988 }
    989 
    990 void ConfigurationPolicyPrefStore::Refresh() {
    991   if (!provider_)
    992     return;
    993 
    994   // Construct a new keeper, determine what changed and swap the keeper in.
    995   scoped_ptr<ConfigurationPolicyPrefKeeper> new_keeper(
    996       new ConfigurationPolicyPrefKeeper(provider_));
    997   std::vector<std::string> changed_prefs;
    998   new_keeper->GetDifferingPrefPaths(policy_keeper_.get(), &changed_prefs);
    999   policy_keeper_.reset(new_keeper.release());
   1000 
   1001   // Send out change notifications.
   1002   for (std::vector<std::string>::const_iterator pref(changed_prefs.begin());
   1003        pref != changed_prefs.end();
   1004        ++pref) {
   1005     FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
   1006                       OnPrefValueChanged(*pref));
   1007   }
   1008 
   1009   // Update the initialization flag.
   1010   if (!initialization_complete_ &&
   1011       provider_->IsInitializationComplete()) {
   1012     initialization_complete_ = true;
   1013     FOR_EACH_OBSERVER(PrefStore::Observer, observers_,
   1014                       OnInitializationCompleted());
   1015   }
   1016 }
   1017 
   1018 }  // namespace policy
   1019