device_settings_provider.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/cros/cros_library.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/cros/network_library.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings_names.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_cache.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/app_pack_updater.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/browser_policy_connector.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/cloud_policy_constants.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/policy/proto/device_management_backend.pb.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/options/options_util.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/google_update_settings.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using google::protobuf::RepeatedPtrField;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// List of settings handled by the DeviceSettingsProvider.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kKnownSettings[] = {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefAllowGuest,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefAllowNewUser,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefEphemeralUsersEnabled,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefShowUserNamesOnSignIn,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAccountsPrefUsers,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kAppPack,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kDeviceOwner,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kIdleLogoutTimeout,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kIdleLogoutWarningDuration,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kPolicyMissingMitigationMode,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReleaseChannel,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReleaseChannelDelegated,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReportDeviceActivityTimes,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReportDeviceBootMode,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReportDeviceLocation,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReportDeviceVersionInfo,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kScreenSaverExtensionId,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kScreenSaverTimeout,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kSettingProxyEverywhere,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kSignedDataRoamingEnabled,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStartUpUrls,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kStatsReportingPref,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kSystemTimezonePolicy,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Legacy policy file location. Used to detect migration from pre v12 ChromeOS.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsControlledSetting(const std::string& pref_path) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char** end = kKnownSettings + arraysize(kKnownSettings);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::find(kKnownSettings, end, pref_path) != end;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasOldMetricsFile() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pastarmovj): Remove this once migration is not needed anymore.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the value is not set we should try to migrate legacy consent file.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Loading consent file state causes us to do blocking IO on UI thread.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Temporarily allow it until we fix http://crbug.com/62626
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ThreadRestrictions::ScopedAllowIO allow_io;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GoogleUpdateSettings::GetCollectStatsConsent();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceSettingsProvider::DeviceSettingsProvider(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NotifyObserversCallback& notify_cb,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceSettingsService* device_settings_service)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : CrosSettingsProvider(notify_cb),
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_service_(device_settings_service),
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trusted_status_(TEMPORARILY_UNTRUSTED),
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ownership_status_(device_settings_service_->GetOwnershipStatus()),
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ALLOW_THIS_IN_INITIALIZER_LIST(store_callback_factory_(this)) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->AddObserver(this);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!UpdateFromService()) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure we have at least the cache data immediately.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RetrieveCachedData();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceSettingsProvider::~DeviceSettingsProvider() {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->RemoveObserver(this);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DoSet(const std::string& path,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const base::Value& in_value) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that either the current user is the device owner or the
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // device doesn't have an owner yet.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!(device_settings_service_->HasPrivateOwnerKey() ||
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Revert UI change.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyObservers(path);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsControlledSetting(path)) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!store_callback_factory_.HasWeakPtrs())
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetInPolicy();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Try to set unhandled cros setting " << path;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::OwnershipStatusChanged() {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeviceSettingsService::OwnershipStatus new_ownership_status =
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_service_->GetOwnershipStatus();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the device just became owned, write the settings accumulated in the
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cache to device settings proper. It is important that writing only happens
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in this case, as during normal operation, the contents of the cache should
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // never overwrite actual device settings.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_service_->HasPrivateOwnerKey()) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // There shouldn't be any pending writes, since the cache writes are all
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // immediate.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!store_callback_factory_.HasWeakPtrs());
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Apply the locally-accumulated device settings on top of the initial
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // settings from the service and write back the result.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (device_settings_service_->device_settings()) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      em::ChromeDeviceSettingsProto new_settings(
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          *device_settings_service_->device_settings());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_settings.MergeFrom(device_settings_);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_settings_.Swap(&new_settings);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StoreDeviceSettings();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The owner key might have become available, allowing migration to happen.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AttemptMigration();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ownership_status_ = new_ownership_status;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DeviceSettingsUpdated() {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!store_callback_factory_.HasWeakPtrs())
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateAndProceedStoring();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::RetrieveCachedData() {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyData policy_data;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!device_settings_cache::Retrieve(&policy_data,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       g_browser_process->local_state()) ||
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !device_settings_.ParseFromString(policy_data.policy_value())) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateValuesCache(policy_data, device_settings_);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::SetInPolicy() {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pending_changes_.empty()) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (RequestTrustedEntity() != TRUSTED) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Re-sync device settings before proceeding.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_settings_service_->Load();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string prop(pending_changes_.front().first);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(pending_changes_.front().second);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_changes_.pop_front();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trusted_status_ = TEMPORARILY_UNTRUSTED;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (prop == kAccountsPrefAllowNewUser) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::AllowNewUsersProto* allow =
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_allow_new_users();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool allow_value;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&allow_value))
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      allow->set_allow_new_users(allow_value);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kAccountsPrefAllowGuest) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::GuestModeEnabledProto* guest =
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_guest_mode_enabled();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool guest_value;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&guest_value))
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      guest->set_guest_mode_enabled(guest_value);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::ShowUserNamesOnSigninProto* show =
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_show_user_names();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool show_value;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&show_value))
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      show->set_show_user_names(show_value);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kSignedDataRoamingEnabled) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::DataRoamingEnabledProto* roam =
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_data_roaming_enabled();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool roaming_value = false;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&roaming_value))
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      roam->set_data_roaming_enabled(roaming_value);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ApplyRoamingSetting(roaming_value);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kSettingProxyEverywhere) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string proxy_value;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsString(&proxy_value)) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool success =
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          device_settings_.mutable_device_proxy_settings()->ParseFromString(
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              proxy_value);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(success);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kReleaseChannel) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::ReleaseChannelProto* release_channel =
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_release_channel();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string channel_value;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsString(&channel_value))
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      release_channel->set_release_channel(channel_value);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kStatsReportingPref) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::MetricsEnabledProto* metrics =
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_metrics_enabled();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool metrics_value = false;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&metrics_value))
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      metrics->set_metrics_enabled(metrics_value);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ApplyMetricsSetting(false, metrics_value);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kAccountsPrefUsers) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::UserWhitelistProto* whitelist_proto =
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_user_whitelist();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    whitelist_proto->clear_user_whitelist();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue& users = static_cast<base::ListValue&>(*value);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (base::ListValue::const_iterator i = users.begin();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         i != users.end(); ++i) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string email;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if ((*i)->GetAsString(&email))
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        whitelist_proto->add_user_whitelist(email.c_str());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (prop == kAccountsPrefEphemeralUsersEnabled) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_.mutable_ephemeral_users_enabled();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ephemeral_users_enabled_value = false;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value->GetAsBoolean(&ephemeral_users_enabled_value)) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ephemeral_users_enabled->set_ephemeral_users_enabled(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ephemeral_users_enabled_value);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The remaining settings don't support Set(), since they are not
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // intended to be customizable by the user:
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kAppPack
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kDeviceOwner
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kIdleLogoutTimeout
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kIdleLogoutWarningDuration
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReleaseChannelDelegated
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReportDeviceVersionInfo
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReportDeviceActivityTimes
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReportDeviceBootMode
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kReportDeviceLocation
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kScreenSaverExtensionId
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kScreenSaverTimeout
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kStartUpUrls
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   kSystemTimezonePolicy
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(FATAL) << "Device setting " << prop << " is read-only.";
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyData data;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.set_username(device_settings_service_->GetUsername());
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the cache to the updated value.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateValuesCache(data, device_settings_);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!device_settings_cache::Store(data, g_browser_process->local_state()))
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Couldn't store to the temp storage.";
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StoreDeviceSettings();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // OnStorePolicyCompleted won't get called in this case so proceed with any
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pending operations immediately.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pending_changes_.empty())
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetInPolicy();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeLoginPolicies(
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For all our boolean settings the following is applicable:
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // true is default permissive value and false is safe prohibitive value.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exceptions:
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   kSignedDataRoamingEnabled has a default value of false.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   kAccountsPrefEphemeralUsersEnabled has a default value of false.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_allow_new_users() &&
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.allow_new_users().has_allow_new_users() &&
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.allow_new_users().allow_new_users()) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // New users allowed, user_whitelist() ignored.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (!policy.has_user_whitelist()) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we have the allow_new_users bool, and it is true, we honor that above.
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In all other cases (don't have it, have it and it is set to false, etc),
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We will honor the user_whitelist() if it is there and populated.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Otherwise we default to allowing new users.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetBoolean(
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kAccountsPrefAllowNewUser,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        policy.user_whitelist().user_whitelist_size() == 0);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kAccountsPrefAllowGuest,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.has_guest_mode_enabled() ||
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.guest_mode_enabled().has_guest_mode_enabled() ||
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.guest_mode_enabled().guest_mode_enabled());
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kAccountsPrefShowUserNamesOnSignIn,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.has_show_user_names() ||
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.show_user_names().has_show_user_names() ||
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.show_user_names().show_user_names());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kAccountsPrefEphemeralUsersEnabled,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.has_ephemeral_users_enabled() &&
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.ephemeral_users_enabled().ephemeral_users_enabled());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ListValue* list = new base::ListValue();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RepeatedPtrField<std::string>& whitelist =
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      whitelist_proto.user_whitelist();
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != whitelist.end(); ++it) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list->Append(base::Value::CreateStringValue(*it));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetValue(kAccountsPrefUsers, list);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeKioskPolicies(
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_forced_logout_timeouts()) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.forced_logout_timeouts().has_idle_logout_timeout()) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetInteger(
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kIdleLogoutTimeout,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.forced_logout_timeouts().idle_logout_timeout());
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.forced_logout_timeouts().has_idle_logout_warning_duration()) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetInteger(
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kIdleLogoutWarningDuration,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.forced_logout_timeouts().idle_logout_warning_duration());
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_login_screen_saver()) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.login_screen_saver().has_screen_saver_timeout()) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetInteger(
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kScreenSaverTimeout,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.login_screen_saver().screen_saver_timeout());
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.login_screen_saver().has_screen_saver_extension_id()) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetString(
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kScreenSaverExtensionId,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.login_screen_saver().screen_saver_extension_id());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_app_pack()) {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef RepeatedPtrField<em::AppPackEntryProto> proto_type;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue* list = new base::ListValue;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const proto_type& app_pack = policy.app_pack().app_pack();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (proto_type::const_iterator it = app_pack.begin();
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != app_pack.end(); ++it) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::DictionaryValue* entry = new base::DictionaryValue;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (it->has_extension_id()) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry->SetString(policy::AppPackUpdater::kExtensionId,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         it->extension_id());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (it->has_update_url())
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry->SetString(policy::AppPackUpdater::kUpdateUrl, it->update_url());
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->Append(entry);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetValue(kAppPack, list);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_start_up_urls()) {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue* list = new base::ListValue();
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::StartUpUrlsProto& urls_proto = policy.start_up_urls();
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RepeatedPtrField<std::string>& urls = urls_proto.start_up_urls();
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (RepeatedPtrField<std::string>::const_iterator it = urls.begin();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != urls.end(); ++it) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->Append(base::Value::CreateStringValue(*it));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetValue(kStartUpUrls, list);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeNetworkPolicies(
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kSignedDataRoamingEnabled,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.has_data_roaming_enabled() &&
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.data_roaming_enabled().has_data_roaming_enabled() &&
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.data_roaming_enabled().data_roaming_enabled());
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(cmasone): NOTIMPLEMENTED() once http://crosbug.com/13052 is fixed.
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string serialized;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_device_proxy_settings() &&
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.device_proxy_settings().SerializeToString(&serialized)) {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetString(kSettingProxyEverywhere, serialized);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeReportingPolicies(
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_device_reporting()) {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.device_reporting().has_report_version_info()) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetBoolean(
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kReportDeviceVersionInfo,
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.device_reporting().report_version_info());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.device_reporting().has_report_activity_times()) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetBoolean(
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kReportDeviceActivityTimes,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.device_reporting().report_activity_times());
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.device_reporting().has_report_boot_mode()) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetBoolean(
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kReportDeviceBootMode,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.device_reporting().report_boot_mode());
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Device location reporting needs to pass privacy review before it can be
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // enabled. crosbug.com/24681
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if (policy.device_reporting().has_report_location()) {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   new_values_cache->SetBoolean(
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //       kReportDeviceLocation,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //       policy.device_reporting().report_location());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // }
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::DecodeGenericPolicies(
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& policy,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap* new_values_cache) const {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_metrics_enabled()) {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetBoolean(kStatsReportingPref,
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 policy.metrics_enabled().metrics_enabled());
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetBoolean(kStatsReportingPref, HasOldMetricsFile());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!policy.has_release_channel() ||
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy.release_channel().has_release_channel()) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Default to an invalid channel (will be ignored).
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetString(kReleaseChannel, "");
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache->SetString(kReleaseChannel,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                policy.release_channel().release_channel());
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_values_cache->SetBoolean(
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kReleaseChannelDelegated,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.has_release_channel() &&
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.release_channel().has_release_channel_delegated() &&
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      policy.release_channel().release_channel_delegated());
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy.has_system_timezone()) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (policy.system_timezone().has_timezone()) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_values_cache->SetString(
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kSystemTimezonePolicy,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy.system_timezone().timezone());
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::UpdateValuesCache(
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::PolicyData& policy_data,
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& settings) {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap new_values_cache;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (policy_data.has_username() && !policy_data.has_request_token())
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_values_cache.SetString(kDeviceOwner, policy_data.username());
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeLoginPolicies(settings, &new_values_cache);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeKioskPolicies(settings, &new_values_cache);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeNetworkPolicies(settings, &new_values_cache);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeReportingPolicies(settings, &new_values_cache);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecodeGenericPolicies(settings, &new_values_cache);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collect all notifications but send them only after we have swapped the
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cache so that if somebody actually reads the cache will be already valid.
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> notifications;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go through the new values and verify in the old ones.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefValueMap::iterator iter = new_values_cache.begin();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; iter != new_values_cache.end(); ++iter) {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value* old_value;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!values_cache_.GetValue(iter->first, &old_value) ||
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !old_value->Equals(iter->second)) {
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notifications.push_back(iter->first);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now check for values that have been removed from the policy blob.
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value* value;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!new_values_cache.GetValue(iter->first, &value))
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notifications.push_back(iter->first);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swap and notify.
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  values_cache_.Swap(&new_values_cache);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < notifications.size(); ++i)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyObservers(notifications[i]);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 bool new_value) {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pastarmovj): Remove this once migration is not needed anymore.
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the value is not set we should try to migrate legacy consent file.
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (use_file) {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_value = HasOldMetricsFile();
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure the values will get eventually written to the policy file.
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    migration_values_.SetValue(kStatsReportingPref,
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::Value::CreateBooleanValue(new_value));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AttemptMigration();
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(INFO) << "No metrics policy set will revert to checking "
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << "consent file which is "
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << (new_value ? "on." : "off.");
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Metrics policy is being set to : " << new_value
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "(use file : " << use_file << ")";
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pastarmovj): Remove this once we don't need to regenerate the
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // consent file for the GUID anymore.
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OptionsUtil::ResolveMetricsReportingEnabled(new_value);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const NetworkDevice* cellular = cros->FindCellularDevice();
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cellular) {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool device_value = cellular->data_roaming_allowed();
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!device_value && cros->IsCellularAlwaysInRoaming()) {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If operator requires roaming always enabled, ignore supplied value
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // and set data roaming allowed in true always.
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cros->SetCellularDataRoamingAllowed(true);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (device_value != new_value) {
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cros->SetCellularDataRoamingAllowed(new_value);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::ApplySideEffects(
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const em::ChromeDeviceSettingsProto& settings) {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First migrate metrics settings as needed.
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (settings.has_metrics_enabled())
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ApplyMetricsSetting(true, false);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Next set the roaming setting as needed.
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ApplyRoamingSetting(
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings.has_data_roaming_enabled() ?
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          settings.data_roaming_enabled().data_roaming_enabled() :
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          false);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeviceSettingsProvider::MitigateMissingPolicy() {
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First check if the device has been owned already and if not exit
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // immediately.
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_browser_process->browser_policy_connector()->GetDeviceMode() !=
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          policy::DEVICE_MODE_CONSUMER) {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we are here the policy file were corrupted or missing. This can happen
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because we are migrating Pre R11 device to the new secure policies or there
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // was an attempt to circumvent policy system. In this case we should populate
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the policy cache with "safe-mode" defaults which should allow the owner to
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // log in but lock the device for anyone else until the policy blob has been
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // recreated by the session manager.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(ERROR) << "Corruption of the policy data has been detected."
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << "Switching to \"safe-mode\" policies until the owner logs in "
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             << "to regenerate the policy data.";
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_.Clear();
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::PolicyData empty_policy_data;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateValuesCache(empty_policy_data, device_settings_);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trusted_status_ = TRUSTED;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsControlledSetting(path)) {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value* value;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (values_cache_.GetValue(path, &value))
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return value;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Trying to get non cros setting.";
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceSettingsProvider::TrustedStatus
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrustedStatus status = RequestTrustedEntity();
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callbacks_.push_back(cb);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return status;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return IsControlledSetting(path);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceSettingsProvider::TrustedStatus
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceSettingsProvider::RequestTrustedEntity() {
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUSTED;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return trusted_status_;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::UpdateAndProceedStoring() {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Re-sync the cache from the service.
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateFromService();
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trigger the next change if necessary.
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (trusted_status_ == TRUSTED && !pending_changes_.empty())
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetInPolicy();
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeviceSettingsProvider::UpdateFromService() {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool settings_loaded = false;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (device_settings_service_->status()) {
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_SUCCESS: {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const em::PolicyData* policy_data =
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          device_settings_service_->policy_data();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const em::ChromeDeviceSettingsProto* device_settings =
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          device_settings_service_->device_settings();
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (policy_data && device_settings) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UpdateValuesCache(*policy_data, *device_settings);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device_settings_ = *device_settings;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trusted_status_ = TRUSTED;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // TODO(pastarmovj): Make those side effects responsibility of the
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // respective subsystems.
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ApplySideEffects(*device_settings);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        settings_loaded = true;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Initial policy load is still pending.
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trusted_status_ = TEMPORARILY_UNTRUSTED;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_NO_POLICY:
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (MitigateMissingPolicy())
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // fall through.
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG(1) << "No policies present yet, will use the temp storage.";
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trusted_status_ = PERMANENTLY_UNTRUSTED;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_POLICY_ERROR:
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_VALIDATION_ERROR:
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_INVALID_POLICY:
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_OPERATION_FAILED:
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << device_settings_service_->status();
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trusted_status_ = PERMANENTLY_UNTRUSTED;
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR:
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The policy has failed to validate due to temporary error but it might
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // take a long time until we recover so behave as it is a permanent error.
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve cros policies because a temporary "
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << "validation error has occurred. Retrying might succeed.";
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      trusted_status_ = PERMANENTLY_UNTRUSTED;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notify the observers we are done.
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<base::Closure> callbacks;
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callbacks.swap(callbacks_);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < callbacks.size(); ++i)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callbacks[i].Run();
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return settings_loaded;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::StoreDeviceSettings() {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mute all previous callbacks to guarantee the |pending_changes_| queue is
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // processed serially.
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_callback_factory_.InvalidateWeakPtrs();
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  device_settings_service_->SignAndStore(
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<em::ChromeDeviceSettingsProto>(
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new em::ChromeDeviceSettingsProto(device_settings_)),
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DeviceSettingsProvider::UpdateAndProceedStoring,
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 store_callback_factory_.GetWeakPtr()));
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeviceSettingsProvider::AttemptMigration() {
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (device_settings_service_->HasPrivateOwnerKey()) {
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrefValueMap::const_iterator i;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DoSet(i->first, *i->second);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    migration_values_.Clear();
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
745