This source file includes following definitions.
- GetSettingsEnforcementGroup
 
- GetTrackingConfiguration
 
- HandleReadError
 
- CreateProfilePrefStoreManager
 
- PrepareFactory
 
- UpdateAllPrefHashStoresIfRequired
 
- CreateLocalState
 
- CreateProfilePrefs
 
- SchedulePrefsFilePathVerification
 
- DisableDelaysAndDomainCheckForTesting
 
- SchedulePrefHashStoresUpdateCheck
 
- ResetPrefHashStore
 
- InitializePrefsFromMasterPrefs
 
- GetResetTime
 
- ClearResetTime
 
- RegisterProfilePrefs
 
- RegisterPrefs
 
#include "chrome/browser/prefs/chrome_pref_service_factory.h"
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/debug/trace_event.h"
#include "base/files/file_path.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/prefs/default_pref_store.h"
#include "base/prefs/json_pref_store.h"
#include "base/prefs/pref_filter.h"
#include "base/prefs/pref_notifier_impl.h"
#include "base/prefs/pref_registry.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/pref_store.h"
#include "base/prefs/pref_value_store.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/prefs/command_line_pref_store.h"
#include "chrome/browser/prefs/pref_hash_filter.h"
#include "chrome/browser/prefs/pref_model_associator.h"
#include "chrome/browser/prefs/pref_service_syncable.h"
#include "chrome/browser/prefs/pref_service_syncable_factory.h"
#include "chrome/browser/prefs/profile_pref_store_manager.h"
#include "chrome/browser/profiles/file_path_verifier_win.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/profile_error_dialog.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/pref_names.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/resource/resource_bundle.h"
#if defined(ENABLE_CONFIGURATION_POLICY)
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/browser/configuration_policy_pref_store.h"
#include "components/policy/core/common/policy_types.h"
#endif
#if defined(ENABLE_MANAGED_USERS)
#include "chrome/browser/managed_mode/supervised_user_pref_store.h"
#endif
#if defined(OS_WIN)
#include "base/win/win_util.h"
#if defined(ENABLE_RLZ)
#include "rlz/lib/machine_id.h"
#endif  
#endif  
using content::BrowserContext;
using content::BrowserThread;
namespace {
bool g_disable_delays_and_domain_check_for_testing = false;
const PrefHashFilter::TrackedPreferenceMetadata kTrackedPrefs[] = {
  {
    0, prefs::kShowHomeButton,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    1, prefs::kHomePageIsNewTabPage,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    2, prefs::kHomePage,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    3, prefs::kRestoreOnStartup,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    4, prefs::kURLsToRestoreOnStartup,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    5, extensions::pref_names::kExtensions,
    PrefHashFilter::NO_ENFORCEMENT,
    PrefHashFilter::TRACKING_STRATEGY_SPLIT
  },
  {
    6, prefs::kGoogleServicesLastUsername,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    7, prefs::kSearchProviderOverrides,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    8, prefs::kDefaultSearchProviderSearchURL,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    9, prefs::kDefaultSearchProviderKeyword,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    10, prefs::kDefaultSearchProviderName,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
#if !defined(OS_ANDROID)
  {
    11, prefs::kPinnedTabs,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
#endif
  {
    12, extensions::pref_names::kKnownDisabled,
    PrefHashFilter::NO_ENFORCEMENT,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
  {
    13, prefs::kProfileResetPromptMemento,
    PrefHashFilter::ENFORCE_ON_LOAD,
    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
  },
};
const size_t kTrackedPrefsReportingIDsCount = 14;
COMPILE_ASSERT(kTrackedPrefsReportingIDsCount >= arraysize(kTrackedPrefs),
               need_to_increment_ids_count);
enum SettingsEnforcementGroup {
  GROUP_NO_ENFORCEMENT,
  
  
  GROUP_ENFORCE_ON_LOAD,
  
  GROUP_ENFORCE_ALWAYS,
  
  GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS,
  
  GROUP_ENFORCE_DEFAULT
};
SettingsEnforcementGroup GetSettingsEnforcementGroup() {
# if defined(OS_WIN)
  if (!g_disable_delays_and_domain_check_for_testing) {
    static bool first_call = true;
    static const bool is_enrolled_to_domain = base::win::IsEnrolledToDomain();
    if (first_call) {
      UMA_HISTOGRAM_BOOLEAN("Settings.TrackedPreferencesNoEnforcementOnDomain",
                            is_enrolled_to_domain);
      first_call = false;
    }
    if (is_enrolled_to_domain)
      return GROUP_NO_ENFORCEMENT;
  }
#endif
  struct {
    const char* group_name;
    SettingsEnforcementGroup group;
  } static const kEnforcementLevelMap[] = {
    { chrome_prefs::internals::kSettingsEnforcementGroupNoEnforcement,
      GROUP_NO_ENFORCEMENT },
    { chrome_prefs::internals::kSettingsEnforcementGroupEnforceOnload,
      GROUP_ENFORCE_ON_LOAD },
    { chrome_prefs::internals::kSettingsEnforcementGroupEnforceAlways,
      GROUP_ENFORCE_ALWAYS },
    { chrome_prefs::internals::
          kSettingsEnforcementGroupEnforceAlwaysWithExtensions,
      GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS },
  };
  
  
  SettingsEnforcementGroup enforcement_group = GROUP_ENFORCE_DEFAULT;
  bool group_determined_from_trial = false;
  base::FieldTrial* trial =
      base::FieldTrialList::Find(
          chrome_prefs::internals::kSettingsEnforcementTrialName);
  if (trial) {
    const std::string& group_name = trial->group_name();
    
    
    
    
    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kEnforcementLevelMap); ++i) {
      if (kEnforcementLevelMap[i].group_name == group_name) {
        enforcement_group = kEnforcementLevelMap[i].group;
        group_determined_from_trial = true;
        break;
      }
    }
  }
  UMA_HISTOGRAM_BOOLEAN("Settings.EnforcementGroupDeterminedFromTrial",
                        group_determined_from_trial);
  return enforcement_group;
}
std::vector<PrefHashFilter::TrackedPreferenceMetadata>
GetTrackingConfiguration() {
  const SettingsEnforcementGroup enforcement_group =
      GetSettingsEnforcementGroup();
  std::vector<PrefHashFilter::TrackedPreferenceMetadata> result;
  for (size_t i = 0; i < arraysize(kTrackedPrefs); ++i) {
    PrefHashFilter::TrackedPreferenceMetadata data = kTrackedPrefs[i];
    switch (enforcement_group) {
      case GROUP_NO_ENFORCEMENT:
        
        data.enforcement_level = PrefHashFilter::NO_ENFORCEMENT;
        break;
      case GROUP_ENFORCE_ON_LOAD:  
      case GROUP_ENFORCE_ALWAYS:
        
        break;
      case GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS:  
      case GROUP_ENFORCE_DEFAULT:
        
        if (data.name == extensions::pref_names::kExtensions)
          data.enforcement_level = PrefHashFilter::ENFORCE_ON_LOAD;
    }
    result.push_back(data);
  }
  return result;
}
void HandleReadError(PersistentPrefStore::PrefReadError error) {
  
  
  UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error,
                            PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM);
  if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
#if !defined(OS_CHROMEOS)
    
    
    
    int message_id = 0;
    if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
      message_id = IDS_PREFERENCES_CORRUPT_ERROR;
    } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
      message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
    }
    if (message_id) {
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                              base::Bind(&ShowProfileErrorDialog,
                                         PROFILE_ERROR_PREFERENCES,
                                         message_id));
    }
#else
    
    
#endif
  }
}
scoped_ptr<ProfilePrefStoreManager> CreateProfilePrefStoreManager(
    const base::FilePath& profile_path) {
  std::string device_id;
#if defined(OS_WIN) && defined(ENABLE_RLZ)
  
  
  
  
  
  
  rlz_lib::GetMachineId(&device_id);
#endif
  return make_scoped_ptr(new ProfilePrefStoreManager(
      profile_path,
      GetTrackingConfiguration(),
      kTrackedPrefsReportingIDsCount,
      ResourceBundle::GetSharedInstance()
          .GetRawDataResource(IDR_PREF_HASH_SEED_BIN)
          .as_string(),
      device_id,
      g_browser_process->local_state()));
}
void PrepareFactory(
    PrefServiceSyncableFactory* factory,
    policy::PolicyService* policy_service,
    ManagedUserSettingsService* managed_user_settings,
    scoped_refptr<PersistentPrefStore> user_pref_store,
    const scoped_refptr<PrefStore>& extension_prefs,
    bool async) {
#if defined(ENABLE_CONFIGURATION_POLICY)
  using policy::ConfigurationPolicyPrefStore;
  factory->set_managed_prefs(
      make_scoped_refptr(new ConfigurationPolicyPrefStore(
          policy_service,
          g_browser_process->browser_policy_connector()->GetHandlerList(),
          policy::POLICY_LEVEL_MANDATORY)));
  factory->set_recommended_prefs(
      make_scoped_refptr(new ConfigurationPolicyPrefStore(
          policy_service,
          g_browser_process->browser_policy_connector()->GetHandlerList(),
          policy::POLICY_LEVEL_RECOMMENDED)));
#endif  
#if defined(ENABLE_MANAGED_USERS)
  if (managed_user_settings) {
    factory->set_supervised_user_prefs(
        make_scoped_refptr(new SupervisedUserPrefStore(managed_user_settings)));
  }
#endif
  factory->set_async(async);
  factory->set_extension_prefs(extension_prefs);
  factory->set_command_line_prefs(
      make_scoped_refptr(
          new CommandLinePrefStore(CommandLine::ForCurrentProcess())));
  factory->set_read_error_callback(base::Bind(&HandleReadError));
  factory->set_user_prefs(user_pref_store);
}
void UpdateAllPrefHashStoresIfRequired(
    const base::FilePath& ignored_profile_path) {
  if (GetSettingsEnforcementGroup() >= GROUP_ENFORCE_ALWAYS)
    return;
  const ProfileInfoCache& profile_info_cache =
      g_browser_process->profile_manager()->GetProfileInfoCache();
  const size_t n_profiles = profile_info_cache.GetNumberOfProfiles();
  for (size_t i = 0; i < n_profiles; ++i) {
    const base::FilePath profile_path =
        profile_info_cache.GetPathOfProfileAtIndex(i);
    if (profile_path != ignored_profile_path) {
      CreateProfilePrefStoreManager(profile_path)
          ->UpdateProfileHashStoreIfRequired(
              JsonPrefStore::GetTaskRunnerForFile(
                  profile_path, BrowserThread::GetBlockingPool()));
    }
  }
}
}  
namespace chrome_prefs {
namespace internals {
const char kSettingsEnforcementTrialName[] = "SettingsEnforcement";
const char kSettingsEnforcementGroupNoEnforcement[] = "no_enforcement";
const char kSettingsEnforcementGroupEnforceOnload[] = "enforce_on_load";
const char kSettingsEnforcementGroupEnforceAlways[] = "enforce_always";
const char kSettingsEnforcementGroupEnforceAlwaysWithExtensions[] =
    "enforce_always_with_extensions";
}  
scoped_ptr<PrefService> CreateLocalState(
    const base::FilePath& pref_filename,
    base::SequencedTaskRunner* pref_io_task_runner,
    policy::PolicyService* policy_service,
    const scoped_refptr<PrefRegistry>& pref_registry,
    bool async) {
  PrefServiceSyncableFactory factory;
  PrepareFactory(
      &factory,
      policy_service,
      NULL,  
      new JsonPrefStore(
          pref_filename, pref_io_task_runner, scoped_ptr<PrefFilter>()),
      NULL,  
      async);
  return factory.Create(pref_registry.get());
}
scoped_ptr<PrefServiceSyncable> CreateProfilePrefs(
    const base::FilePath& profile_path,
    base::SequencedTaskRunner* pref_io_task_runner,
    policy::PolicyService* policy_service,
    ManagedUserSettingsService* managed_user_settings,
    const scoped_refptr<PrefStore>& extension_prefs,
    const scoped_refptr<user_prefs::PrefRegistrySyncable>& pref_registry,
    bool async) {
  TRACE_EVENT0("browser", "chrome_prefs::CreateProfilePrefs");
  PrefServiceSyncableFactory factory;
  PrepareFactory(&factory,
                 policy_service,
                 managed_user_settings,
                 scoped_refptr<PersistentPrefStore>(
                     CreateProfilePrefStoreManager(profile_path)
                         ->CreateProfilePrefStore(pref_io_task_runner)),
                 extension_prefs,
                 async);
  return factory.CreateSyncable(pref_registry.get());
}
void SchedulePrefsFilePathVerification(const base::FilePath& profile_path) {
#if defined(OS_WIN)
  
  const int kVerifyPrefsFileDelaySeconds = 60;
  BrowserThread::GetBlockingPool()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&VerifyPreferencesFile,
                 ProfilePrefStoreManager::GetPrefFilePathFromProfilePath(
                     profile_path)),
      base::TimeDelta::FromSeconds(g_disable_delays_and_domain_check_for_testing
                                       ? 0
                                       : kVerifyPrefsFileDelaySeconds));
#endif
}
void DisableDelaysAndDomainCheckForTesting() {
  g_disable_delays_and_domain_check_for_testing = true;
}
void SchedulePrefHashStoresUpdateCheck(
    const base::FilePath& initial_profile_path) {
  if (!ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking) {
    ProfilePrefStoreManager::ResetAllPrefHashStores(
        g_browser_process->local_state());
    return;
  }
  const int kDefaultPrefHashStoresUpdateCheckDelaySeconds = 55;
  BrowserThread::PostDelayedTask(
        BrowserThread::UI,
        FROM_HERE,
        base::Bind(&UpdateAllPrefHashStoresIfRequired,
                   initial_profile_path),
        base::TimeDelta::FromSeconds(
            g_disable_delays_and_domain_check_for_testing ?
                0 : kDefaultPrefHashStoresUpdateCheckDelaySeconds));
}
void ResetPrefHashStore(const base::FilePath& profile_path) {
  CreateProfilePrefStoreManager(profile_path)->ResetPrefHashStore();
}
bool InitializePrefsFromMasterPrefs(
    const base::FilePath& profile_path,
    const base::DictionaryValue& master_prefs) {
  return CreateProfilePrefStoreManager(profile_path)
      ->InitializePrefsFromMasterPrefs(master_prefs);
}
base::Time GetResetTime(Profile* profile) {
  return ProfilePrefStoreManager::GetResetTime(profile->GetPrefs());
}
void ClearResetTime(Profile* profile) {
  ProfilePrefStoreManager::ClearResetTime(profile->GetPrefs());
}
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
  ProfilePrefStoreManager::RegisterProfilePrefs(registry);
}
void RegisterPrefs(PrefRegistrySimple* registry) {
  ProfilePrefStoreManager::RegisterPrefs(registry);
}
}