| Index: chrome/browser/chromeos/user_cros_settings_provider.cc
|
| diff --git a/chrome/browser/chromeos/user_cros_settings_provider.cc b/chrome/browser/chromeos/user_cros_settings_provider.cc
|
| deleted file mode 100644
|
| index 7d855dff978796bbf9dfff1e3cf8fc51420e3046..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/chromeos/user_cros_settings_provider.cc
|
| +++ /dev/null
|
| @@ -1,536 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/chromeos/user_cros_settings_provider.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/callback.h"
|
| -#include "base/hash_tables.h"
|
| -#include "base/logging.h"
|
| -#include "base/memory/singleton.h"
|
| -#include "base/string_util.h"
|
| -#include "base/values.h"
|
| -#include "chrome/browser/browser_process.h"
|
| -#include "chrome/browser/chromeos/cros/cros_library.h"
|
| -#include "chrome/browser/chromeos/cros/network_library.h"
|
| -#include "chrome/browser/chromeos/cros_settings.h"
|
| -#include "chrome/browser/chromeos/cros_settings_names.h"
|
| -#include "chrome/browser/chromeos/login/ownership_service.h"
|
| -#include "chrome/browser/chromeos/login/ownership_status_checker.h"
|
| -#include "chrome/browser/chromeos/login/user_manager.h"
|
| -#include "chrome/browser/prefs/pref_service.h"
|
| -#include "chrome/browser/prefs/pref_value_map.h"
|
| -#include "chrome/browser/prefs/scoped_user_pref_update.h"
|
| -#include "chrome/browser/ui/options/options_util.h"
|
| -#include "chrome/common/chrome_notification_types.h"
|
| -#include "chrome/installer/util/google_update_settings.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "content/public/browser/notification_service.h"
|
| -
|
| -using content::BrowserThread;
|
| -
|
| -namespace chromeos {
|
| -
|
| -namespace {
|
| -
|
| -const char kTrueIncantation[] = "true";
|
| -const char kFalseIncantation[] = "false";
|
| -const char kTrustedSuffix[] = "/trusted";
|
| -
|
| -// For all our boolean settings following is applicable:
|
| -// true is default permissive value and false is safe prohibitic value.
|
| -// Exception: kSignedDataRoamingEnabled which has default value of false.
|
| -const char* kBooleanSettings[] = {
|
| - kAccountsPrefAllowNewUser,
|
| - kAccountsPrefAllowGuest,
|
| - kAccountsPrefShowUserNamesOnSignIn,
|
| - kSignedDataRoamingEnabled,
|
| - kStatsReportingPref
|
| -};
|
| -
|
| -const char* kStringSettings[] = {
|
| - kDeviceOwner,
|
| - kReleaseChannel
|
| -};
|
| -
|
| -const char* kListSettings[] = {
|
| - kAccountsPrefUsers
|
| -};
|
| -
|
| -// This class provides the means to migrate settings to the signed settings
|
| -// store. It does one of three things - store the settings in the policy blob
|
| -// immediately if the current user is the owner. Uses the
|
| -// SignedSettingsTempStorage if there is no owner yet, or waits for an
|
| -// OWNERSHIP_CHECKED notification to delay the storing until the owner has
|
| -// logged in.
|
| -class MigrationHelper : public content::NotificationObserver {
|
| - public:
|
| - explicit MigrationHelper() : callback_(NULL) {
|
| - registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_CHECKED,
|
| - content::NotificationService::AllSources());
|
| - }
|
| -
|
| - void set_callback(SignedSettingsHelper::Callback* callback) {
|
| - callback_ = callback;
|
| - }
|
| -
|
| - void AddMigrationValue(const std::string& path, base::Value* value) {
|
| - migration_values_.SetValue(path, value);
|
| - }
|
| -
|
| - void MigrateValues(void) {
|
| - ownership_checker_.reset(new OwnershipStatusChecker(
|
| - base::Bind(&MigrationHelper::DoMigrateValues, base::Unretained(this))));
|
| - }
|
| -
|
| - // NotificationObserver overrides:
|
| - virtual void Observe(int type,
|
| - const content::NotificationSource& source,
|
| - const content::NotificationDetails& details) OVERRIDE {
|
| - if (type == chrome::NOTIFICATION_OWNERSHIP_CHECKED)
|
| - MigrateValues();
|
| - }
|
| -
|
| - private:
|
| - void DoMigrateValues(OwnershipService::Status status,
|
| - bool current_user_is_owner) {
|
| - ownership_checker_.reset(NULL);
|
| -
|
| - // We can call StartStorePropertyOp in two cases - either if the owner is
|
| - // currently logged in and the policy can be updated immediately or if there
|
| - // is no owner yet in which case the value will be temporarily stored in the
|
| - // SignedSettingsTempStorage until the device is owned. If none of these
|
| - // cases is met then we will wait for user change notification and retry.
|
| - if (current_user_is_owner || status != OwnershipService::OWNERSHIP_TAKEN) {
|
| - PrefValueMap::const_iterator i;
|
| - for (i = migration_values_.begin(); i != migration_values_.end(); ++i) {
|
| - // Queue all values for storing.
|
| - SignedSettingsHelper::Get()->StartStorePropertyOp(i->first, *i->second,
|
| - callback_);
|
| - }
|
| - migration_values_.Clear();
|
| - }
|
| - }
|
| -
|
| - content::NotificationRegistrar registrar_;
|
| - scoped_ptr<OwnershipStatusChecker> ownership_checker_;
|
| - SignedSettingsHelper::Callback* callback_;
|
| - PrefValueMap migration_values_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(MigrationHelper);
|
| -};
|
| -
|
| -bool IsControlledBooleanSetting(const std::string& pref_path) {
|
| - // TODO(nkostylev): Using std::find for 4 value array generates this warning
|
| - // in chroot stl_algo.h:231: error: array subscript is above array bounds.
|
| - // GCC 4.4.3
|
| - return (pref_path == kAccountsPrefAllowNewUser) ||
|
| - (pref_path == kAccountsPrefAllowGuest) ||
|
| - (pref_path == kAccountsPrefShowUserNamesOnSignIn) ||
|
| - (pref_path == kSignedDataRoamingEnabled) ||
|
| - (pref_path == kStatsReportingPref);
|
| -}
|
| -
|
| -bool IsControlledStringSetting(const std::string& pref_path) {
|
| - return std::find(kStringSettings,
|
| - kStringSettings + arraysize(kStringSettings),
|
| - pref_path) !=
|
| - kStringSettings + arraysize(kStringSettings);
|
| -}
|
| -
|
| -bool IsControlledListSetting(const std::string& pref_path) {
|
| - return std::find(kListSettings,
|
| - kListSettings + arraysize(kListSettings),
|
| - pref_path) !=
|
| - kListSettings + arraysize(kListSettings);
|
| -}
|
| -
|
| -bool IsControlledSetting(const std::string& pref_path) {
|
| - return (IsControlledBooleanSetting(pref_path) ||
|
| - IsControlledStringSetting(pref_path) ||
|
| - IsControlledListSetting(pref_path));
|
| -}
|
| -
|
| -void RegisterSetting(PrefService* local_state, const std::string& pref_path) {
|
| - local_state->RegisterBooleanPref((pref_path + kTrustedSuffix).c_str(),
|
| - false,
|
| - PrefService::UNSYNCABLE_PREF);
|
| - if (IsControlledBooleanSetting(pref_path)) {
|
| - if (pref_path == kSignedDataRoamingEnabled ||
|
| - pref_path == kStatsReportingPref)
|
| - local_state->RegisterBooleanPref(pref_path.c_str(),
|
| - false,
|
| - PrefService::UNSYNCABLE_PREF);
|
| - else
|
| - local_state->RegisterBooleanPref(pref_path.c_str(),
|
| - true,
|
| - PrefService::UNSYNCABLE_PREF);
|
| - } else if (IsControlledStringSetting(pref_path)) {
|
| - local_state->RegisterStringPref(pref_path.c_str(),
|
| - "",
|
| - PrefService::UNSYNCABLE_PREF);
|
| - } else {
|
| - DCHECK(IsControlledListSetting(pref_path));
|
| - local_state->RegisterListPref(pref_path.c_str(),
|
| - PrefService::UNSYNCABLE_PREF);
|
| - }
|
| -}
|
| -
|
| -enum UseValue {
|
| - USE_VALUE_SUPPLIED,
|
| - USE_VALUE_DEFAULT
|
| -};
|
| -
|
| -void UpdateCache(const std::string& name,
|
| - const base::Value* value,
|
| - UseValue use_value) {
|
| - PrefService* prefs = g_browser_process->local_state();
|
| - if (use_value == USE_VALUE_DEFAULT)
|
| - prefs->ClearPref(name.c_str());
|
| - else
|
| - prefs->Set(name.c_str(), *value);
|
| - prefs->ScheduleSavePersistentPrefs();
|
| -}
|
| -
|
| -class UserCrosSettingsTrust : public SignedSettingsHelper::Callback {
|
| - public:
|
| - static UserCrosSettingsTrust* GetInstance() {
|
| - return Singleton<UserCrosSettingsTrust>::get();
|
| - }
|
| -
|
| - // Working horse for UserCrosSettingsProvider::RequestTrusted* family.
|
| - bool RequestTrustedEntity(const std::string& name) {
|
| - OwnershipService::Status ownership_status =
|
| - ownership_service_->GetStatus(false);
|
| - if (ownership_status == OwnershipService::OWNERSHIP_NONE)
|
| - return true;
|
| - PrefService* prefs = g_browser_process->local_state();
|
| - if (prefs->IsManagedPreference(name.c_str()))
|
| - return true;
|
| - if (ownership_status == OwnershipService::OWNERSHIP_TAKEN) {
|
| - DCHECK(g_browser_process);
|
| - PrefService* prefs = g_browser_process->local_state();
|
| - DCHECK(prefs);
|
| - if (prefs->GetBoolean((name + kTrustedSuffix).c_str()))
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - bool RequestTrustedEntity(const std::string& name,
|
| - const base::Closure& callback) {
|
| - if (RequestTrustedEntity(name)) {
|
| - return true;
|
| - } else {
|
| - if (!callback.is_null())
|
| - callbacks_[name].push_back(callback);
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - void Reload() {
|
| - for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
|
| - StartFetchingSetting(kBooleanSettings[i]);
|
| - for (size_t i = 0; i < arraysize(kStringSettings); ++i)
|
| - StartFetchingSetting(kStringSettings[i]);
|
| - for (size_t i = 0; i < arraysize(kListSettings); ++i)
|
| - StartFetchingSetting(kListSettings[i]);
|
| - }
|
| -
|
| - void Set(const std::string& path, const base::Value& in_value) {
|
| - PrefService* prefs = g_browser_process->local_state();
|
| - DCHECK(!prefs->IsManagedPreference(path.c_str()));
|
| -
|
| - if (!UserManager::Get()->current_user_is_owner()) {
|
| - LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
|
| -
|
| - // Revert UI change.
|
| - CrosSettings::Get()->FireObservers(path.c_str());
|
| - return;
|
| - }
|
| - if (IsControlledSetting(path)) {
|
| - if (IsControlledBooleanSetting(path)) {
|
| - bool bool_value = false;
|
| - if (in_value.GetAsBoolean(&bool_value)) {
|
| - OnBooleanPropertyChange(path, bool_value);
|
| - }
|
| - }
|
| - SignedSettingsHelper::Get()->StartStorePropertyOp(
|
| - path, in_value, this);
|
| - UpdateCache(path, &in_value, USE_VALUE_SUPPLIED);
|
| -
|
| - LOG(ERROR) << "Set cros setting " << path;
|
| - } else {
|
| - LOG(WARNING) << "Try to set unhandled cros setting " << path;
|
| - }
|
| - }
|
| -
|
| - private:
|
| - // upper bound for number of retries to fetch a signed setting.
|
| - static const int kNumRetriesLimit = 9;
|
| -
|
| - UserCrosSettingsTrust()
|
| - : ownership_service_(OwnershipService::GetSharedInstance()),
|
| - retries_left_(kNumRetriesLimit) {
|
| - migration_helper_.set_callback(this);
|
| - // Start prefetching Boolean and String preferences.
|
| - Reload();
|
| - }
|
| -
|
| - virtual ~UserCrosSettingsTrust() {
|
| - if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| - // Cancels all pending callbacks from us.
|
| - SignedSettingsHelper::Get()->CancelCallback(this);
|
| - }
|
| - }
|
| -
|
| - // Called right before boolean property is changed.
|
| - void OnBooleanPropertyChange(const std::string& path, bool new_value) {
|
| - if (path == kSignedDataRoamingEnabled) {
|
| - NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
|
| - if (cros->IsCellularAlwaysInRoaming()) {
|
| - // If operator requires roaming always enabled, ignore supplied value
|
| - // and set data roaming allowed in true always.
|
| - new_value = true;
|
| - }
|
| - cros->SetCellularDataRoamingAllowed(new_value);
|
| - } else if (path == kStatsReportingPref) {
|
| - // TODO(pastarmovj): Remove this once we don't need to regenerate the
|
| - // consent file for the GUID anymore.
|
| - OptionsUtil::ResolveMetricsReportingEnabled(new_value);
|
| - }
|
| - }
|
| -
|
| - // Called right after signed value was checked.
|
| - void OnPropertyRetrieve(const std::string& path,
|
| - const base::Value* value,
|
| - UseValue use_value) {
|
| - if (path == kSignedDataRoamingEnabled) {
|
| - NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
|
| - const NetworkDevice* cellular = cros->FindCellularDevice();
|
| - if (cellular) {
|
| - bool device_value = cellular->data_roaming_allowed();
|
| - if (!device_value && cros->IsCellularAlwaysInRoaming()) {
|
| - // If operator requires roaming always enabled, ignore supplied value
|
| - // and set data roaming allowed in true always.
|
| - cros->SetCellularDataRoamingAllowed(true);
|
| - } else {
|
| - bool new_value = false;
|
| - if (use_value == USE_VALUE_SUPPLIED)
|
| - value->GetAsBoolean(&new_value);
|
| - if (device_value != new_value)
|
| - cros->SetCellularDataRoamingAllowed(new_value);
|
| - }
|
| - }
|
| - } else if (path == kStatsReportingPref) {
|
| - bool stats_consent = false;
|
| - if (use_value == USE_VALUE_SUPPLIED)
|
| - value->GetAsBoolean(&stats_consent);
|
| - // TODO(pastarmovj): Remove this once migration is not needed anymore.
|
| - // If the value is not set we should try to migrate legacy consent file.
|
| - if (use_value == USE_VALUE_DEFAULT) {
|
| - // Loading consent file state causes us to do blocking IO on UI thread.
|
| - // Temporarily allow it until we fix http://crbug.com/62626
|
| - base::ThreadRestrictions::ScopedAllowIO allow_io;
|
| - stats_consent = GoogleUpdateSettings::GetCollectStatsConsent();
|
| - // Make sure the values will get eventually written to the policy file.
|
| - migration_helper_.AddMigrationValue(
|
| - path, base::Value::CreateBooleanValue(stats_consent));
|
| - migration_helper_.MigrateValues();
|
| - base::FundamentalValue base_value(stats_consent);
|
| - UpdateCache(path, &base_value, USE_VALUE_SUPPLIED);
|
| - LOG(WARNING) << "No metrics policy set will revert to checking "
|
| - << "consent file which is "
|
| - << (stats_consent ? "on." : "off.");
|
| - }
|
| - // TODO(pastarmovj): Remove this once we don't need to regenerate the
|
| - // consent file for the GUID anymore.
|
| - VLOG(1) << "Metrics policy is being set to : " << stats_consent
|
| - << "(reason : " << use_value << ")";
|
| - OptionsUtil::ResolveMetricsReportingEnabled(stats_consent);
|
| - }
|
| - }
|
| -
|
| - void StartFetchingSetting(const std::string& name) {
|
| - DCHECK(g_browser_process);
|
| - PrefService* prefs = g_browser_process->local_state();
|
| - if (!prefs)
|
| - return;
|
| - // Do not trust before fetching complete.
|
| - prefs->ClearPref((name + kTrustedSuffix).c_str());
|
| - prefs->ScheduleSavePersistentPrefs();
|
| - SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
|
| - }
|
| -
|
| - // Implementation of SignedSettingsHelper::Callback.
|
| - virtual void OnRetrievePropertyCompleted(SignedSettings::ReturnCode code,
|
| - const std::string& name,
|
| - const base::Value* value) {
|
| - if (!IsControlledSetting(name)) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - bool is_owned = ownership_service_->GetStatus(true) ==
|
| - OwnershipService::OWNERSHIP_TAKEN;
|
| - PrefService* prefs = g_browser_process->local_state();
|
| - switch (code) {
|
| - case SignedSettings::SUCCESS:
|
| - case SignedSettings::NOT_FOUND:
|
| - case SignedSettings::KEY_UNAVAILABLE: {
|
| - bool fallback_to_default = !is_owned
|
| - || (code == SignedSettings::NOT_FOUND);
|
| - DCHECK(fallback_to_default || code == SignedSettings::SUCCESS);
|
| - if (fallback_to_default)
|
| - VLOG(1) << "Going default for cros setting " << name;
|
| - else
|
| - VLOG(1) << "Retrieved cros setting " << name;
|
| - UpdateCache(
|
| - name, value,
|
| - fallback_to_default ? USE_VALUE_DEFAULT : USE_VALUE_SUPPLIED);
|
| - OnPropertyRetrieve(
|
| - name, value,
|
| - fallback_to_default ? USE_VALUE_DEFAULT : USE_VALUE_SUPPLIED);
|
| - break;
|
| - }
|
| - case SignedSettings::OPERATION_FAILED:
|
| - default: {
|
| - DCHECK(code == SignedSettings::OPERATION_FAILED);
|
| - DCHECK(is_owned);
|
| - LOG(ERROR) << "On owned device: failed to retrieve cros "
|
| - "setting, name=" << name;
|
| - if (retries_left_ > 0) {
|
| - retries_left_ -= 1;
|
| - StartFetchingSetting(name);
|
| - return;
|
| - }
|
| - LOG(ERROR) << "No retries left";
|
| - if (IsControlledBooleanSetting(name)) {
|
| - // For boolean settings we can just set safe (false) values
|
| - // and continue as trusted.
|
| - scoped_ptr<base::Value> false_value(
|
| - base::Value::CreateBooleanValue(false));
|
| - OnPropertyRetrieve(name, false_value.get(), USE_VALUE_SUPPLIED);
|
| - UpdateCache(name, false_value.get(), USE_VALUE_SUPPLIED);
|
| - } else {
|
| - prefs->ClearPref((name + kTrustedSuffix).c_str());
|
| - return;
|
| - }
|
| - break;
|
| - }
|
| - }
|
| - prefs->SetBoolean((name + kTrustedSuffix).c_str(), true);
|
| - {
|
| - std::vector<base::Closure>& callbacks_vector = callbacks_[name];
|
| - for (size_t i = 0; i < callbacks_vector.size(); ++i)
|
| - MessageLoop::current()->PostTask(FROM_HERE, callbacks_vector[i]);
|
| - callbacks_vector.clear();
|
| - }
|
| - if (code == SignedSettings::SUCCESS)
|
| - CrosSettings::Get()->FireObservers(name.c_str());
|
| - }
|
| -
|
| - // Implementation of SignedSettingsHelper::Callback.
|
| - virtual void OnStorePropertyCompleted(SignedSettings::ReturnCode code,
|
| - const std::string& name,
|
| - const base::Value& value) {
|
| - VLOG(1) << "Store cros setting " << name << ", code=" << code;
|
| -
|
| - // Reload the setting if store op fails.
|
| - if (code != SignedSettings::SUCCESS)
|
| - SignedSettingsHelper::Get()->StartRetrieveProperty(name, this);
|
| - }
|
| -
|
| - // Implementation of SignedSettingsHelper::Callback.
|
| - virtual void OnWhitelistCompleted(SignedSettings::ReturnCode code,
|
| - const std::string& email) {
|
| - VLOG(1) << "Add " << email << " to whitelist, code=" << code;
|
| -
|
| - // Reload the whitelist on settings op failure.
|
| - if (code != SignedSettings::SUCCESS)
|
| - CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
|
| - }
|
| -
|
| - // Implementation of SignedSettingsHelper::Callback.
|
| - virtual void OnUnwhitelistCompleted(SignedSettings::ReturnCode code,
|
| - const std::string& email) {
|
| - VLOG(1) << "Remove " << email << " from whitelist, code=" << code;
|
| -
|
| - // Reload the whitelist on settings op failure.
|
| - if (code != SignedSettings::SUCCESS)
|
| - CrosSettings::Get()->FireObservers(kAccountsPrefUsers);
|
| - }
|
| -
|
| - // Pending callbacks that need to be invoked after settings verification.
|
| - base::hash_map<std::string, std::vector<base::Closure> > callbacks_;
|
| -
|
| - OwnershipService* ownership_service_;
|
| - MigrationHelper migration_helper_;
|
| -
|
| - // In order to guard against occasional failure to fetch a property
|
| - // we allow for some number of retries.
|
| - int retries_left_;
|
| -
|
| - friend class SignedSettingsHelper;
|
| - friend struct DefaultSingletonTraits<UserCrosSettingsTrust>;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(UserCrosSettingsTrust);
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -} // namespace chromeos
|
| -
|
| -namespace chromeos {
|
| -
|
| -UserCrosSettingsProvider::UserCrosSettingsProvider() {
|
| - // Trigger prefetching of settings.
|
| - UserCrosSettingsTrust::GetInstance();
|
| -}
|
| -
|
| -// static
|
| -void UserCrosSettingsProvider::RegisterPrefs(PrefService* local_state) {
|
| - for (size_t i = 0; i < arraysize(kBooleanSettings); ++i)
|
| - RegisterSetting(local_state, kBooleanSettings[i]);
|
| - for (size_t i = 0; i < arraysize(kStringSettings); ++i)
|
| - RegisterSetting(local_state, kStringSettings[i]);
|
| - for (size_t i = 0; i < arraysize(kListSettings); ++i)
|
| - RegisterSetting(local_state, kListSettings[i]);
|
| -}
|
| -
|
| -void UserCrosSettingsProvider::Reload() {
|
| - UserCrosSettingsTrust::GetInstance()->Reload();
|
| -}
|
| -
|
| -void UserCrosSettingsProvider::DoSet(const std::string& path,
|
| - const base::Value& in_value) {
|
| - UserCrosSettingsTrust::GetInstance()->Set(path, in_value);
|
| -}
|
| -
|
| -const base::Value* UserCrosSettingsProvider::Get(
|
| - const std::string& path) const {
|
| - if (HandlesSetting(path)) {
|
| - const PrefService* prefs = g_browser_process->local_state();
|
| - const PrefService::Preference* pref = prefs->FindPreference(path.c_str());
|
| - return pref->GetValue();
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -bool UserCrosSettingsProvider::GetTrusted(const std::string& path,
|
| - const base::Closure& callback) const {
|
| - return UserCrosSettingsTrust::GetInstance()->RequestTrustedEntity(
|
| - path, callback);
|
| -}
|
| -
|
| -bool UserCrosSettingsProvider::HandlesSetting(const std::string& path) const {
|
| - return ::StartsWithASCII(path, "cros.accounts.", true) ||
|
| - ::StartsWithASCII(path, "cros.signed.", true) ||
|
| - ::StartsWithASCII(path, "cros.metrics.", true) ||
|
| - path == kDeviceOwner ||
|
| - path == kReleaseChannel;
|
| -}
|
| -
|
| -} // namespace chromeos
|
|
|