device_settings_provider.cc revision 5e3f23d412006dc4db4e659864679f29341e113f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_provider.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/cros/cros_library.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/cros/network_library.h"
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings_names.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_cache.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/browser_policy_connector.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/options/options_util.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/google_update_settings.h"
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using google::protobuf::RepeatedField;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using google::protobuf::RepeatedPtrField;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// List of settings handled by the DeviceSettingsProvider.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kKnownSettings[] = {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefAllowGuest,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefAllowNewUser,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  kAccountsPrefDeviceLocalAccounts,
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  kAccountsPrefDeviceLocalAccountAutoLoginDelay,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  kAccountsPrefDeviceLocalAccountAutoLoginId,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefEphemeralUsersEnabled,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefShowUserNamesOnSignIn,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefUsers,
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  kAllowRedeemChromeOsRegistrationOffers,
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  kAllowedConnectionTypesForUpdate,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAppPack,
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kDeviceAttestationEnabled,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kDeviceOwner,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kIdleLogoutTimeout,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kIdleLogoutWarningDuration,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kPolicyMissingMitigationMode,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReleaseChannel,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReleaseChannelDelegated,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReportDeviceActivityTimes,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReportDeviceBootMode,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReportDeviceLocation,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReportDeviceVersionInfo,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kScreenSaverExtensionId,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kScreenSaverTimeout,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kSignedDataRoamingEnabled,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kStartUpFlags,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStartUpUrls,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStatsReportingPref,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kSystemTimezonePolicy,
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  kUpdateDisabled,
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  kVariationsRestrictParameter,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Legacy policy file location. Used to detect migration from pre v12 ChromeOS.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences";
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasOldMetricsFile() {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pastarmovj): Remove this once migration is not needed anymore.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the value is not set we should try to migrate legacy consent file.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Loading consent file state causes us to do blocking IO on UI thread.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Temporarily allow it until we fix http://crbug.com/62626
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::ScopedAllowIO allow_io;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GoogleUpdateSettings::GetCollectStatsConsent();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceSettingsProvider::DeviceSettingsProvider(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NotifyObserversCallback& notify_cb,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceSettingsService* device_settings_service)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : CrosSettingsProvider(notify_cb),
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_service_(device_settings_service),
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trusted_status_(TEMPORARILY_UNTRUSTED),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ownership_status_(device_settings_service_->GetOwnershipStatus()),
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      store_callback_factory_(this) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->AddObserver(this);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!UpdateFromService()) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure we have at least the cache data immediately.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RetrieveCachedData();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceSettingsProvider::~DeviceSettingsProvider() {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->RemoveObserver(this);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char** end = kKnownSettings + arraysize(kKnownSettings);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return std::find(kKnownSettings, end, name) != end;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DoSet(const std::string& path,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const base::Value& in_value) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that either the current user is the device owner or the
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // device doesn't have an owner yet.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!(device_settings_service_->HasPrivateOwnerKey() ||
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Revert UI change.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyObservers(path);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsDeviceSetting(path)) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!store_callback_factory_.HasWeakPtrs())
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetInPolicy();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Try to set unhandled cros setting " << path;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::OwnershipStatusChanged() {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeviceSettingsService::OwnershipStatus new_ownership_status =
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_service_->GetOwnershipStatus();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the device just became owned, write the settings accumulated in the
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cache to device settings proper. It is important that writing only happens
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in this case, as during normal operation, the contents of the cache should
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // never overwrite actual device settings.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_service_->HasPrivateOwnerKey()) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // There shouldn't be any pending writes, since the cache writes are all
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // immediate.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!store_callback_factory_.HasWeakPtrs());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Apply the locally-accumulated device settings on top of the initial
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // settings from the service and write back the result.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (device_settings_service_->device_settings()) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      em::ChromeDeviceSettingsProto new_settings(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          *device_settings_service_->device_settings());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_settings.MergeFrom(device_settings_);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_.Swap(&new_settings);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StoreDeviceSettings();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The owner key might have become available, allowing migration to happen.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AttemptMigration();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ownership_status_ = new_ownership_status;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DeviceSettingsUpdated() {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!store_callback_factory_.HasWeakPtrs())
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateAndProceedStoring();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::RetrieveCachedData() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyData policy_data;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!device_settings_cache::Retrieve(&policy_data,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       g_browser_process->local_state()) ||
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !device_settings_.ParseFromString(policy_data.policy_value())) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateValuesCache(policy_data, device_settings_, trusted_status_);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::SetInPolicy() {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pending_changes_.empty()) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (RequestTrustedEntity() != TRUSTED) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Re-sync device settings before proceeding.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_settings_service_->Load();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string prop(pending_changes_.front().first);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(pending_changes_.front().second);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_changes_.pop_front();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trusted_status_ = TEMPORARILY_UNTRUSTED;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (prop == kAccountsPrefAllowNewUser) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::AllowNewUsersProto* allow =
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_allow_new_users();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool allow_value;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&allow_value))
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      allow->set_allow_new_users(allow_value);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kAccountsPrefAllowGuest) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::GuestModeEnabledProto* guest =
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_guest_mode_enabled();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool guest_value;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&guest_value))
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      guest->set_guest_mode_enabled(guest_value);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::ShowUserNamesOnSigninProto* show =
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_show_user_names();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool show_value;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&show_value))
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      show->set_show_user_names(show_value);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (prop == kAccountsPrefDeviceLocalAccounts) {
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    em::DeviceLocalAccountsProto* device_local_accounts =
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        device_settings_.mutable_device_local_accounts();
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    device_local_accounts->clear_account();
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::ListValue* accounts_list = NULL;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetAsList(&accounts_list)) {
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (base::ListValue::const_iterator entry(accounts_list->begin());
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           entry != accounts_list->end(); ++entry) {
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        const base::DictionaryValue* entry_dict = NULL;
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if ((*entry)->GetAsDictionary(&entry_dict)) {
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          em::DeviceLocalAccountInfoProto* account =
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              device_local_accounts->add_account();
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          std::string account_id;
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          if (entry_dict->GetStringWithoutPathExpansion(
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) {
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            account->set_account_id(account_id);
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          }
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          int type;
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          if (entry_dict->GetIntegerWithoutPathExpansion(
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  kAccountsPrefDeviceLocalAccountsKeyType, &type)) {
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            account->set_type(
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                static_cast<em::DeviceLocalAccountInfoProto::AccountType>(
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    type));
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          }
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          std::string kiosk_app_id;
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          if (entry_dict->GetStringWithoutPathExpansion(
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  &kiosk_app_id)) {
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            account->mutable_kiosk_app()->set_app_id(kiosk_app_id);
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          }
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          std::string kiosk_app_update_url;
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          if (entry_dict->GetStringWithoutPathExpansion(
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  &kiosk_app_update_url)) {
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            account->mutable_kiosk_app()->set_update_url(kiosk_app_update_url);
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          }
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } else {
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          NOTREACHED();
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginId) {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    em::DeviceLocalAccountsProto* device_local_accounts =
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        device_settings_.mutable_device_local_accounts();
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string id;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetAsString(&id))
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_local_accounts->set_auto_login_id(id);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginDelay) {
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    em::DeviceLocalAccountsProto* device_local_accounts =
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        device_settings_.mutable_device_local_accounts();
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int delay;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetAsInteger(&delay))
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_local_accounts->set_auto_login_delay(delay);
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) {
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    em::DeviceLocalAccountsProto* device_local_accounts =
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        device_settings_.mutable_device_local_accounts();
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool enabled;
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (value->GetAsBoolean(&enabled))
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      device_local_accounts->set_enable_auto_login_bailout(enabled);
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NOTREACHED();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kSignedDataRoamingEnabled) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::DataRoamingEnabledProto* roam =
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_data_roaming_enabled();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool roaming_value = false;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&roaming_value))
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      roam->set_data_roaming_enabled(roaming_value);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ApplyRoamingSetting(roaming_value);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kReleaseChannel) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::ReleaseChannelProto* release_channel =
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_release_channel();
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string channel_value;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsString(&channel_value))
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      release_channel->set_release_channel(channel_value);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kStatsReportingPref) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::MetricsEnabledProto* metrics =
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_metrics_enabled();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool metrics_value = false;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&metrics_value))
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      metrics->set_metrics_enabled(metrics_value);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ApplyMetricsSetting(false, metrics_value);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kAccountsPrefUsers) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::UserWhitelistProto* whitelist_proto =
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_user_whitelist();
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    whitelist_proto->clear_user_whitelist();
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue* users;
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetAsList(&users)) {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (base::ListValue::const_iterator i = users->begin();
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           i != users->end(); ++i) {
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::string email;
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if ((*i)->GetAsString(&email))
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          whitelist_proto->add_user_whitelist(email);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kAccountsPrefEphemeralUsersEnabled) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_ephemeral_users_enabled();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ephemeral_users_enabled_value = false;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&ephemeral_users_enabled_value)) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ephemeral_users_enabled->set_ephemeral_users_enabled(
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ephemeral_users_enabled_value);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (prop == kAllowRedeemChromeOsRegistrationOffers) {
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers =
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        device_settings_.mutable_allow_redeem_offers();
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool allow_redeem_offers_value;
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetAsBoolean(&allow_redeem_offers_value)) {
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      allow_redeem_offers->set_allow_redeem_offers(
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          allow_redeem_offers_value);
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (prop == kStartUpFlags) {
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    em::StartUpFlagsProto* flags_proto =
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        device_settings_.mutable_start_up_flags();
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    flags_proto->Clear();
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::ListValue* flags;
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (value->GetAsList(&flags)) {
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (base::ListValue::const_iterator i = flags->begin();
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           i != flags->end(); ++i) {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::string flag;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if ((*i)->GetAsString(&flag))
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          flags_proto->add_flags(flag);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The remaining settings don't support Set(), since they are not
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // intended to be customizable by the user:
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kAppPack
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    //   kDeviceAttestationEnabled
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kDeviceOwner
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kIdleLogoutTimeout
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kIdleLogoutWarningDuration
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReleaseChannelDelegated
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReportDeviceVersionInfo
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReportDeviceActivityTimes
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReportDeviceBootMode
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReportDeviceLocation
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kScreenSaverExtensionId
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kScreenSaverTimeout
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kStartUpUrls
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kSystemTimezonePolicy
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    //   kVariationsRestrictParameter
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(FATAL) << "Device setting " << prop << " is read-only.";
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyData data;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.set_username(device_settings_service_->GetUsername());
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the cache to the updated value.
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateValuesCache(data, device_settings_, trusted_status_);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StoreDeviceSettings();
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!device_settings_cache::Store(data, g_browser_process->local_state()))
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Couldn't store to the temp storage.";
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // OnStorePolicyCompleted won't get called in this case so proceed with any
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pending operations immediately.
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pending_changes_.empty())
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetInPolicy();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeLoginPolicies(
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For all our boolean settings the following is applicable:
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // true is default permissive value and false is safe prohibitive value.
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exceptions:
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   kSignedDataRoamingEnabled has a default value of false.
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   kAccountsPrefEphemeralUsersEnabled has a default value of false.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_allow_new_users() &&
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      policy.allow_new_users().has_allow_new_users()) {
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (policy.allow_new_users().allow_new_users()) {
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // New users allowed, user whitelist ignored.
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // New users not allowed, enforce user whitelist if present.
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new_values_cache->SetBoolean(kAccountsPrefAllowNewUser,
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   !policy.has_user_whitelist());
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // No configured allow-new-users value, enforce whitelist if non-empty.
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    new_values_cache->SetBoolean(
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        kAccountsPrefAllowNewUser,
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        policy.user_whitelist().user_whitelist_size() == 0);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kAccountsPrefAllowGuest,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.has_guest_mode_enabled() ||
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.guest_mode_enabled().has_guest_mode_enabled() ||
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.guest_mode_enabled().guest_mode_enabled());
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kAccountsPrefShowUserNamesOnSignIn,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.has_show_user_names() ||
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.show_user_names().has_show_user_names() ||
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.show_user_names().show_user_names());
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kAccountsPrefEphemeralUsersEnabled,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.has_ephemeral_users_enabled() &&
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.ephemeral_users_enabled().ephemeral_users_enabled());
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ListValue* list = new base::ListValue();
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RepeatedPtrField<std::string>& whitelist =
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      whitelist_proto.user_whitelist();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != whitelist.end(); ++it) {
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list->Append(new base::StringValue(*it));
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetValue(kAccountsPrefUsers, list);
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::ListValue> account_list(new base::ListValue());
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!command_line->HasSwitch(switches::kDisableLocalAccounts)) {
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const em::DeviceLocalAccountsProto device_local_accounts_proto =
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        policy.device_local_accounts();
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        device_local_accounts_proto.account();
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (entry->has_type()) {
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (entry->has_account_id()) {
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          entry_dict->SetStringWithoutPathExpansion(
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              kAccountsPrefDeviceLocalAccountsKeyId, entry->account_id());
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        entry_dict->SetIntegerWithoutPathExpansion(
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            kAccountsPrefDeviceLocalAccountsKeyType, entry->type());
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (entry->kiosk_app().has_app_id()) {
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          entry_dict->SetStringWithoutPathExpansion(
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              entry->kiosk_app().app_id());
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (entry->kiosk_app().has_update_url()) {
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          entry_dict->SetStringWithoutPathExpansion(
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              entry->kiosk_app().update_url());
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
488b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      } else if (entry->has_deprecated_public_session_id()) {
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Deprecated public session specification.
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        entry_dict->SetStringWithoutPathExpansion(
491b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            kAccountsPrefDeviceLocalAccountsKeyId,
492b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            entry->deprecated_public_session_id());
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        entry_dict->SetIntegerWithoutPathExpansion(
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            kAccountsPrefDeviceLocalAccountsKeyType,
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      account_list->Append(entry_dict.release());
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts,
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             account_list.release());
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (policy.has_device_local_accounts()) {
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (policy.device_local_accounts().has_auto_login_id()) {
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_values_cache->SetString(
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          kAccountsPrefDeviceLocalAccountAutoLoginId,
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          policy.device_local_accounts().auto_login_id());
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (policy.device_local_accounts().has_auto_login_delay()) {
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_values_cache->SetInteger(
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          kAccountsPrefDeviceLocalAccountAutoLoginDelay,
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          policy.device_local_accounts().auto_login_delay());
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  new_values_cache->SetBoolean(
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      policy.device_local_accounts().enable_auto_login_bailout());
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (policy.has_start_up_flags()) {
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::ListValue* list = new base::ListValue();
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const em::StartUpFlagsProto& flags_proto = policy.start_up_flags();
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const RepeatedPtrField<std::string>& flags = flags_proto.flags();
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (RepeatedPtrField<std::string>::const_iterator it = flags.begin();
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         it != flags.end(); ++it) {
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      list->Append(new base::StringValue(*it));
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    new_values_cache->SetValue(kStartUpFlags, list);
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeKioskPolicies(
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_forced_logout_timeouts()) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.forced_logout_timeouts().has_idle_logout_timeout()) {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetInteger(
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kIdleLogoutTimeout,
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.forced_logout_timeouts().idle_logout_timeout());
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetInteger(
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kIdleLogoutWarningDuration,
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.forced_logout_timeouts().idle_logout_warning_duration());
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_login_screen_saver()) {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.login_screen_saver().has_screen_saver_timeout()) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetInteger(
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kScreenSaverTimeout,
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.login_screen_saver().screen_saver_timeout());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.login_screen_saver().has_screen_saver_extension_id()) {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetString(
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kScreenSaverExtensionId,
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.login_screen_saver().screen_saver_extension_id());
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_app_pack()) {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef RepeatedPtrField<em::AppPackEntryProto> proto_type;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue* list = new base::ListValue;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const proto_type& app_pack = policy.app_pack().app_pack();
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (proto_type::const_iterator it = app_pack.begin();
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != app_pack.end(); ++it) {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::DictionaryValue* entry = new base::DictionaryValue;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (it->has_extension_id()) {
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        entry->SetStringWithoutPathExpansion(kAppPackKeyExtensionId,
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             it->extension_id());
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (it->has_update_url()) {
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        entry->SetStringWithoutPathExpansion(kAppPackKeyUpdateUrl,
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             it->update_url());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->Append(entry);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetValue(kAppPack, list);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_start_up_urls()) {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue* list = new base::ListValue();
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::StartUpUrlsProto& urls_proto = policy.start_up_urls();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls();
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (RepeatedPtrField<std::string>::const_iterator it = urls.begin();
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != urls.end(); ++it) {
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      list->Append(new base::StringValue(*it));
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetValue(kStartUpUrls, list);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeNetworkPolicies(
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kSignedDataRoamingEnabled,
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.has_data_roaming_enabled() &&
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.data_roaming_enabled().has_data_roaming_enabled() &&
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.data_roaming_enabled().data_roaming_enabled());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void DeviceSettingsProvider::DecodeAutoUpdatePolicies(
606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!policy.has_auto_update_settings())
609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const em::AutoUpdateSettingsProto& au_settings_proto =
611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      policy.auto_update_settings();
612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (au_settings_proto.has_update_disabled()) {
613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    new_values_cache->SetBoolean(kUpdateDisabled,
614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 au_settings_proto.update_disabled());
615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const RepeatedField<int>& allowed_connection_types =
617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      au_settings_proto.allowed_connection_types();
618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::ListValue* list = new base::ListValue();
619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (RepeatedField<int>::const_iterator i = allowed_connection_types.begin(),
620868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           e = allowed_connection_types.end(); i != e; ++i) {
621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    list->Append(new base::FundamentalValue(*i));
622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  new_values_cache->SetValue(kAllowedConnectionTypesForUpdate, list);
624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeReportingPolicies(
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_device_reporting()) {
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.device_reporting().has_report_version_info()) {
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetBoolean(
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kReportDeviceVersionInfo,
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.device_reporting().report_version_info());
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.device_reporting().has_report_activity_times()) {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetBoolean(
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kReportDeviceActivityTimes,
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.device_reporting().report_activity_times());
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.device_reporting().has_report_boot_mode()) {
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetBoolean(
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kReportDeviceBootMode,
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.device_reporting().report_boot_mode());
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Device location reporting needs to pass privacy review before it can be
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // enabled. crosbug.com/24681
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if (policy.device_reporting().has_report_location()) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   new_values_cache->SetBoolean(
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //       kReportDeviceLocation,
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //       policy.device_reporting().report_location());
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // }
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeGenericPolicies(
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_metrics_enabled()) {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetBoolean(kStatsReportingPref,
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 policy.metrics_enabled().metrics_enabled());
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!policy.has_release_channel() ||
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.release_channel().has_release_channel()) {
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Default to an invalid channel (will be ignored).
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetString(kReleaseChannel, "");
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetString(kReleaseChannel,
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                policy.release_channel().release_channel());
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kReleaseChannelDelegated,
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.has_release_channel() &&
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.release_channel().has_release_channel_delegated() &&
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.release_channel().release_channel_delegated());
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_system_timezone()) {
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.system_timezone().has_timezone()) {
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetString(
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kSystemTimezonePolicy,
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.system_timezone().timezone());
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (policy.has_allow_redeem_offers()) {
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_values_cache->SetBoolean(
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kAllowRedeemChromeOsRegistrationOffers,
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        policy.allow_redeem_offers().allow_redeem_offers());
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_values_cache->SetBoolean(
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kAllowRedeemChromeOsRegistrationOffers,
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        true);
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (policy.has_variations_parameter()) {
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    new_values_cache->SetString(
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        kVariationsRestrictParameter,
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        policy.variations_parameter().parameter());
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  new_values_cache->SetBoolean(
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kDeviceAttestationEnabled,
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      policy.attestation_settings().attestation_enabled());
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::UpdateValuesCache(
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::PolicyData& policy_data,
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const em::ChromeDeviceSettingsProto& settings,
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TrustedStatus trusted_status) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap new_values_cache;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy_data.has_username() && !policy_data.has_request_token())
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache.SetString(kDeviceOwner, policy_data.username());
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeLoginPolicies(settings, &new_values_cache);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeKioskPolicies(settings, &new_values_cache);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeNetworkPolicies(settings, &new_values_cache);
721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DecodeAutoUpdatePolicies(settings, &new_values_cache);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeReportingPolicies(settings, &new_values_cache);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeGenericPolicies(settings, &new_values_cache);
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collect all notifications but send them only after we have swapped the
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cache so that if somebody actually reads the cache will be already valid.
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> notifications;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go through the new values and verify in the old ones.
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap::iterator iter = new_values_cache.begin();
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; iter != new_values_cache.end(); ++iter) {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value* old_value;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!values_cache_.GetValue(iter->first, &old_value) ||
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !old_value->Equals(iter->second)) {
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notifications.push_back(iter->first);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now check for values that have been removed from the policy blob.
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value* value;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!new_values_cache.GetValue(iter->first, &value))
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notifications.push_back(iter->first);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swap and notify.
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  values_cache_.Swap(&new_values_cache);
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trusted_status_ = trusted_status;
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < notifications.size(); ++i)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyObservers(notifications[i]);
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 bool new_value) {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pastarmovj): Remove this once migration is not needed anymore.
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the value is not set we should try to migrate legacy consent file.
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (use_file) {
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_value = HasOldMetricsFile();
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure the values will get eventually written to the policy file.
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    migration_values_.SetValue(kStatsReportingPref,
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::Value::CreateBooleanValue(new_value));
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AttemptMigration();
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "No metrics policy set will revert to checking "
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << "consent file which is "
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << (new_value ? "on." : "off.");
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UMA_HISTOGRAM_COUNTS("DeviceSettings.MetricsMigrated", 1);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Metrics policy is being set to : " << new_value
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "(use file : " << use_file << ")";
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pastarmovj): Remove this once we don't need to regenerate the
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // consent file for the GUID anymore.
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OptionsUtil::ResolveMetricsReportingEnabled(new_value);
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) {
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!CrosLibrary::Get())
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;  // May not be initialized in tests.
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const NetworkDevice* cellular = cros->FindCellularDevice();
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cellular) {
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool device_value = cellular->data_roaming_allowed();
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!device_value && cros->IsCellularAlwaysInRoaming()) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If operator requires roaming always enabled, ignore supplied value
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // and set data roaming allowed in true always.
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cros->SetCellularDataRoamingAllowed(true);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (device_value != new_value) {
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cros->SetCellularDataRoamingAllowed(new_value);
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::ApplySideEffects(
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& settings) {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First migrate metrics settings as needed.
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (settings.has_metrics_enabled())
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ApplyMetricsSetting(true, false);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Next set the roaming setting as needed.
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ApplyRoamingSetting(
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings.has_data_roaming_enabled() ?
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          settings.data_roaming_enabled().data_roaming_enabled() :
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          false);
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeviceSettingsProvider::MitigateMissingPolicy() {
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First check if the device has been owned already and if not exit
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // immediately.
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_browser_process->browser_policy_connector()->GetDeviceMode() !=
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy::DEVICE_MODE_CONSUMER) {
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we are here the policy file were corrupted or missing. This can happen
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because we are migrating Pre R11 device to the new secure policies or there
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // was an attempt to circumvent policy system. In this case we should populate
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the policy cache with "safe-mode" defaults which should allow the owner to
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // log in but lock the device for anyone else until the policy blob has been
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // recreated by the session manager.
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(ERROR) << "Corruption of the policy data has been detected."
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << "Switching to \"safe-mode\" policies until the owner logs in "
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << "to regenerate the policy data.";
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_.Clear();
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyData empty_policy_data;
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsDeviceSetting(path)) {
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value* value;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (values_cache_.GetValue(path, &value))
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return value;
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Trying to get non cros setting.";
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceSettingsProvider::TrustedStatus
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrustedStatus status = RequestTrustedEntity();
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callbacks_.push_back(cb);
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return status;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return IsDeviceSetting(path);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceSettingsProvider::TrustedStatus
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceSettingsProvider::RequestTrustedEntity() {
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUSTED;
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return trusted_status_;
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::UpdateAndProceedStoring() {
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Re-sync the cache from the service.
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateFromService();
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trigger the next change if necessary.
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (trusted_status_ == TRUSTED && !pending_changes_.empty())
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetInPolicy();
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeviceSettingsProvider::UpdateFromService() {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool settings_loaded = false;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (device_settings_service_->status()) {
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_SUCCESS: {
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const em::PolicyData* policy_data =
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          device_settings_service_->policy_data();
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const em::ChromeDeviceSettingsProto* device_settings =
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          device_settings_service_->device_settings();
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (policy_data && device_settings) {
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (!device_settings_cache::Store(*policy_data,
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          g_browser_process->local_state())) {
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          LOG(ERROR) << "Couldn't update the local state cache.";
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UpdateValuesCache(*policy_data, *device_settings, TRUSTED);
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_ = *device_settings;
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // TODO(pastarmovj): Make those side effects responsibility of the
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // respective subsystems.
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ApplySideEffects(*device_settings);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        settings_loaded = true;
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Initial policy load is still pending.
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trusted_status_ = TEMPORARILY_UNTRUSTED;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_NO_POLICY:
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (MitigateMissingPolicy())
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // fall through.
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG(1) << "No policies present yet, will use the temp storage.";
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trusted_status_ = PERMANENTLY_UNTRUSTED;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_POLICY_ERROR:
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_VALIDATION_ERROR:
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_INVALID_POLICY:
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_OPERATION_FAILED:
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << device_settings_service_->status();
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trusted_status_ = PERMANENTLY_UNTRUSTED;
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The policy has failed to validate due to temporary error but it might
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // take a long time until we recover so behave as it is a permanent error.
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve cros policies because a temporary "
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << "validation error has occurred. Retrying might succeed.";
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trusted_status_ = PERMANENTLY_UNTRUSTED;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify the observers we are done.
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<base::Closure> callbacks;
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callbacks.swap(callbacks_);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < callbacks.size(); ++i)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callbacks[i].Run();
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return settings_loaded;
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::StoreDeviceSettings() {
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mute all previous callbacks to guarantee the |pending_changes_| queue is
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // processed serially.
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_callback_factory_.InvalidateWeakPtrs();
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->SignAndStore(
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<em::ChromeDeviceSettingsProto>(
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new em::ChromeDeviceSettingsProto(device_settings_)),
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DeviceSettingsProvider::UpdateAndProceedStoring,
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 store_callback_factory_.GetWeakPtr()));
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::AttemptMigration() {
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (device_settings_service_->HasPrivateOwnerKey()) {
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap::const_iterator i;
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DoSet(i->first, *i->second);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    migration_values_.Clear();
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
955