// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/settings/device_settings_provider.h"

#include <memory.h>
#include <stddef.h>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/syslog_logging.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
#include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/chromeos/policy/off_hours/off_hours_proto_parser.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_cache.h"
#include "chrome/browser/chromeos/settings/install_attributes.h"
#include "chrome/browser/chromeos/tpm_firmware_update.h"
#include "chrome/browser/metrics/metrics_reporting_state.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/settings/cros_settings_names.h"
#include "components/policy/core/common/chrome_schema.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/schema.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "components/prefs/pref_service.h"

using google::protobuf::RepeatedField;
using google::protobuf::RepeatedPtrField;

namespace em = enterprise_management;

namespace chromeos {

namespace {

// List of settings handled by the DeviceSettingsProvider.
const char* const kKnownSettings[] = {
    kAccountsPrefAllowGuest,
    kAccountsPrefAllowNewUser,
    kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
    kAccountsPrefDeviceLocalAccountAutoLoginDelay,
    kAccountsPrefDeviceLocalAccountAutoLoginId,
    kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
    kAccountsPrefDeviceLocalAccounts,
    kAccountsPrefEphemeralUsersEnabled,
    kAccountsPrefLoginScreenDomainAutoComplete,
    kAccountsPrefShowUserNamesOnSignIn,
    kAccountsPrefSupervisedUsersEnabled,
    kAccountsPrefTransferSAMLCookies,
    kAccountsPrefUsers,
    kAllowBluetooth,
    kAllowedConnectionTypesForUpdate,
    kAllowRedeemChromeOsRegistrationOffers,
    kAttestationForContentProtectionEnabled,
    kCastReceiverName,
    kDeviceAttestationEnabled,
    kDeviceDisabled,
    kDeviceDisabledMessage,
    kDeviceHostnameTemplate,
    kDeviceLoginScreenAppInstallList,
    kDeviceLoginScreenInputMethods,
    kDeviceLoginScreenLocales,
    kDeviceOffHours,
    kDeviceOwner,
    kDevicePrintersAccessMode,
    kDevicePrintersBlacklist,
    kDevicePrintersConfigurations,
    kDevicePrintersWhitelist,
    kDeviceQuirksDownloadEnabled,
    kDeviceWallpaperImage,
    kDisplayRotationDefault,
    kExtensionCacheSize,
    kHeartbeatEnabled,
    kHeartbeatFrequency,
    kLoginAuthenticationBehavior,
    kLoginVideoCaptureAllowedUrls,
    kMinimumRequiredChromeVersion,
    kPolicyMissingMitigationMode,
    kRebootOnShutdown,
    kReleaseChannel,
    kReleaseChannelDelegated,
    kReportDeviceActivityTimes,
    kReportDeviceBootMode,
    kReportDeviceHardwareStatus,
    kReportDeviceLocation,
    kReportDeviceNetworkInterfaces,
    kReportDeviceSessionStatus,
    kReportDeviceUsers,
    kReportDeviceVersionInfo,
    kReportOsUpdateStatus,
    kReportRunningKioskApp,
    kReportUploadFrequency,
    kServiceAccountIdentity,
    kSignedDataRoamingEnabled,
    kStartUpFlags,
    kStatsReportingPref,
    kSystemLogUploadEnabled,
    kSystemTimezonePolicy,
    kSystemUse24HourClock,
    kTargetVersionPrefix,
    kTPMFirmwareUpdateSettings,
    kUnaffiliatedArcAllowed,
    kUpdateDisabled,
    kVariationsRestrictParameter,
    kVirtualMachinesAllowed,
    kSamlLoginAuthenticationType,
    kDeviceAutoUpdateTimeRestrictions,
};

// Decodes a JSON string to a base::Value, and drops unknown properties
// according to a policy schema. |policy_name| is the name of a policy schema
// defined in policy_templates.json. Returns null in case the input is not a
// valid JSON string.
std::unique_ptr<base::Value> DecodeJsonStringAndDropUnknownBySchema(
    const std::string& json_string,
    const std::string& policy_name) {
  std::string error;
  std::unique_ptr<base::Value> root = base::JSONReader::ReadAndReturnError(
      json_string, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error);

  if (!root) {
    LOG(WARNING) << "Invalid JSON string: " << error << ", ignoring.";
    return nullptr;
  }

  const policy::Schema& schema =
      policy::GetChromeSchema().GetKnownProperty(policy_name);

  if (!schema.valid()) {
    LOG(WARNING) << "Unknown or invalid policy schema for " << policy_name
                 << ".";
    return nullptr;
  }

  std::string error_path;
  bool changed = false;
  if (!schema.Normalize(root.get(), policy::SCHEMA_ALLOW_UNKNOWN, &error_path,
                        &error, &changed)) {
    LOG(WARNING) << "Invalid policy value for " << policy_name << ": " << error
                 << " at " << error_path << ".";
    return nullptr;
  }
  if (changed) {
    LOG(WARNING) << "Some properties in " << policy_name
                 << " were dropped: " << error << " at " << error_path << ".";
  }

  return root;
}

void DecodeLoginPolicies(const em::ChromeDeviceSettingsProto& policy,
                         bool is_enterprise_managed,
                         PrefValueMap* new_values_cache) {
  // For all our boolean settings the following is applicable:
  // true is default permissive value and false is safe prohibitive value.
  // Exceptions:
  //   kAccountsPrefEphemeralUsersEnabled has a default value of false.
  //   kAccountsPrefSupervisedUsersEnabled has a default value of false
  //     for enterprise devices and true for consumer devices.
  //   kAccountsPrefTransferSAMLCookies has a default value of false.
  if (policy.has_allow_new_users() &&
      policy.allow_new_users().has_allow_new_users()) {
    if (policy.allow_new_users().allow_new_users()) {
      // New users allowed, user whitelist ignored.
      new_values_cache->SetBoolean(kAccountsPrefAllowNewUser, true);
    } else {
      // New users not allowed, enforce user whitelist if present.
      new_values_cache->SetBoolean(kAccountsPrefAllowNewUser,
                                   !policy.has_user_whitelist());
    }
  } else {
    // No configured allow-new-users value, enforce whitelist if non-empty.
    new_values_cache->SetBoolean(
        kAccountsPrefAllowNewUser,
        policy.user_whitelist().user_whitelist_size() == 0);
  }

  new_values_cache->SetBoolean(
      kRebootOnShutdown,
      policy.has_reboot_on_shutdown() &&
      policy.reboot_on_shutdown().has_reboot_on_shutdown() &&
      policy.reboot_on_shutdown().reboot_on_shutdown());

  new_values_cache->SetBoolean(
      kAccountsPrefAllowGuest,
      !policy.has_guest_mode_enabled() ||
      !policy.guest_mode_enabled().has_guest_mode_enabled() ||
      policy.guest_mode_enabled().guest_mode_enabled());

  bool supervised_users_enabled = false;
  if (is_enterprise_managed) {
    supervised_users_enabled =
        policy.has_supervised_users_settings() &&
        policy.supervised_users_settings().has_supervised_users_enabled() &&
        policy.supervised_users_settings().supervised_users_enabled();
  } else {
    supervised_users_enabled =
        !policy.has_supervised_users_settings() ||
        !policy.supervised_users_settings().has_supervised_users_enabled() ||
        policy.supervised_users_settings().supervised_users_enabled();
  }
  new_values_cache->SetBoolean(
      kAccountsPrefSupervisedUsersEnabled, supervised_users_enabled);

  new_values_cache->SetBoolean(
      kAccountsPrefShowUserNamesOnSignIn,
      !policy.has_show_user_names() ||
      !policy.show_user_names().has_show_user_names() ||
      policy.show_user_names().show_user_names());

  new_values_cache->SetBoolean(
      kAccountsPrefEphemeralUsersEnabled,
      policy.has_ephemeral_users_enabled() &&
      policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
      policy.ephemeral_users_enabled().ephemeral_users_enabled());

  std::unique_ptr<base::ListValue> list(new base::ListValue());
  const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
  const RepeatedPtrField<std::string>& whitelist =
      whitelist_proto.user_whitelist();
  for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
       it != whitelist.end(); ++it) {
    list->AppendString(*it);
  }
  new_values_cache->SetValue(kAccountsPrefUsers, std::move(list));

  std::unique_ptr<base::ListValue> account_list(new base::ListValue());
  const em::DeviceLocalAccountsProto device_local_accounts_proto =
      policy.device_local_accounts();
  const RepeatedPtrField<em::DeviceLocalAccountInfoProto>& accounts =
      device_local_accounts_proto.account();
  RepeatedPtrField<em::DeviceLocalAccountInfoProto>::const_iterator entry;
  for (entry = accounts.begin(); entry != accounts.end(); ++entry) {
    std::unique_ptr<base::DictionaryValue> entry_dict(
        new base::DictionaryValue());
    if (entry->has_type()) {
      if (entry->has_account_id()) {
        entry_dict->SetKey(kAccountsPrefDeviceLocalAccountsKeyId,
                           base::Value(entry->account_id()));
      }
      entry_dict->SetKey(kAccountsPrefDeviceLocalAccountsKeyType,
                         base::Value(entry->type()));
      if (entry->kiosk_app().has_app_id()) {
        entry_dict->SetKey(kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
                           base::Value(entry->kiosk_app().app_id()));
      }
      if (entry->kiosk_app().has_update_url()) {
        entry_dict->SetKey(kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL,
                           base::Value(entry->kiosk_app().update_url()));
      }
      if (entry->android_kiosk_app().has_package_name()) {
        entry_dict->SetKey(
            chromeos::kAccountsPrefDeviceLocalAccountsKeyArcKioskPackage,
            base::Value(entry->android_kiosk_app().package_name()));
      }
      if (entry->android_kiosk_app().has_class_name()) {
        entry_dict->SetKey(
            chromeos::kAccountsPrefDeviceLocalAccountsKeyArcKioskClass,
            base::Value(entry->android_kiosk_app().class_name()));
      }
      if (entry->android_kiosk_app().has_action()) {
        entry_dict->SetKey(
            chromeos::kAccountsPrefDeviceLocalAccountsKeyArcKioskAction,
            base::Value(entry->android_kiosk_app().action()));
      }
      if (entry->android_kiosk_app().has_display_name()) {
        entry_dict->SetKey(
            chromeos::kAccountsPrefDeviceLocalAccountsKeyArcKioskDisplayName,
            base::Value(entry->android_kiosk_app().display_name()));
      }
    } else if (entry->has_deprecated_public_session_id()) {
      // Deprecated public session specification.
      entry_dict->SetKey(kAccountsPrefDeviceLocalAccountsKeyId,
                         base::Value(entry->deprecated_public_session_id()));
      entry_dict->SetKey(
          kAccountsPrefDeviceLocalAccountsKeyType,
          base::Value(policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION));
    }
    account_list->Append(std::move(entry_dict));
  }
  new_values_cache->SetValue(kAccountsPrefDeviceLocalAccounts,
                             std::move(account_list));

  if (policy.has_device_local_accounts()) {
    if (policy.device_local_accounts().has_auto_login_id()) {
      new_values_cache->SetString(
          kAccountsPrefDeviceLocalAccountAutoLoginId,
          policy.device_local_accounts().auto_login_id());
    }
    if (policy.device_local_accounts().has_auto_login_delay()) {
      new_values_cache->SetInteger(
          kAccountsPrefDeviceLocalAccountAutoLoginDelay,
          policy.device_local_accounts().auto_login_delay());
    }
  }

  new_values_cache->SetBoolean(
      kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled,
      policy.device_local_accounts().enable_auto_login_bailout());
  new_values_cache->SetBoolean(
      kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
      policy.device_local_accounts().prompt_for_network_when_offline());

  if (policy.has_start_up_flags()) {
    std::unique_ptr<base::ListValue> list(new base::ListValue());
    const em::StartUpFlagsProto& flags_proto = policy.start_up_flags();
    const RepeatedPtrField<std::string>& flags = flags_proto.flags();
    for (RepeatedPtrField<std::string>::const_iterator it = flags.begin();
         it != flags.end(); ++it) {
      list->AppendString(*it);
    }
    new_values_cache->SetValue(kStartUpFlags, std::move(list));
  }

  if (policy.has_saml_settings()) {
    new_values_cache->SetBoolean(
        kAccountsPrefTransferSAMLCookies,
        policy.saml_settings().transfer_saml_cookies());
  }

  // The behavior when policy is not set and when it is set to an empty string
  // is the same. Thus lets add policy only if it is set and its value is not
  // an empty string.
  if (policy.has_login_screen_domain_auto_complete() &&
      policy.login_screen_domain_auto_complete()
          .has_login_screen_domain_auto_complete() &&
      !policy.login_screen_domain_auto_complete()
           .login_screen_domain_auto_complete()
           .empty()) {
    new_values_cache->SetString(kAccountsPrefLoginScreenDomainAutoComplete,
                                policy.login_screen_domain_auto_complete()
                                    .login_screen_domain_auto_complete());
  }

  if (policy.has_login_authentication_behavior() &&
      policy.login_authentication_behavior()
          .has_login_authentication_behavior()) {
    new_values_cache->SetInteger(
        kLoginAuthenticationBehavior,
        policy.login_authentication_behavior().login_authentication_behavior());
  }

  if (policy.has_login_video_capture_allowed_urls()) {
    std::unique_ptr<base::ListValue> list(new base::ListValue());
    const em::LoginVideoCaptureAllowedUrlsProto&
        login_video_capture_allowed_urls_proto =
            policy.login_video_capture_allowed_urls();
    for (const auto& value : login_video_capture_allowed_urls_proto.urls()) {
      list->AppendString(value);
    }
    new_values_cache->SetValue(kLoginVideoCaptureAllowedUrls, std::move(list));
  }

  if (policy.has_device_login_screen_app_install_list()) {
    std::unique_ptr<base::ListValue> apps(new base::ListValue);
    const em::DeviceLoginScreenAppInstallListProto& proto(
        policy.device_login_screen_app_install_list());
    for (const auto& app : proto.device_login_screen_app_install_list())
      apps->AppendString(app);
    new_values_cache->SetValue(kDeviceLoginScreenAppInstallList,
                               std::move(apps));
  }

  if (policy.has_login_screen_locales()) {
    std::unique_ptr<base::ListValue> locales(new base::ListValue);
    const em::LoginScreenLocalesProto& login_screen_locales(
        policy.login_screen_locales());
    for (const auto& locale : login_screen_locales.login_screen_locales())
      locales->AppendString(locale);
    new_values_cache->SetValue(kDeviceLoginScreenLocales, std::move(locales));
  }

  if (policy.has_login_screen_input_methods()) {
    std::unique_ptr<base::ListValue> input_methods(new base::ListValue);
    const em::LoginScreenInputMethodsProto& login_screen_input_methods(
        policy.login_screen_input_methods());
    for (const auto& input_method :
         login_screen_input_methods.login_screen_input_methods())
      input_methods->AppendString(input_method);
    new_values_cache->SetValue(kDeviceLoginScreenInputMethods,
                               std::move(input_methods));
  }

  if (policy.has_saml_login_authentication_type() &&
      policy.saml_login_authentication_type()
          .has_saml_login_authentication_type()) {
    new_values_cache->SetInteger(kSamlLoginAuthenticationType,
                                 policy.saml_login_authentication_type()
                                     .saml_login_authentication_type());
  }
}

void DecodeNetworkPolicies(
    const em::ChromeDeviceSettingsProto& policy,
    PrefValueMap* new_values_cache) {
  // kSignedDataRoamingEnabled has a default value of false.
  new_values_cache->SetBoolean(
      kSignedDataRoamingEnabled,
      policy.has_data_roaming_enabled() &&
      policy.data_roaming_enabled().has_data_roaming_enabled() &&
      policy.data_roaming_enabled().data_roaming_enabled());
}

void DecodeAutoUpdatePolicies(
    const em::ChromeDeviceSettingsProto& policy,
    PrefValueMap* new_values_cache) {
  if (policy.has_auto_update_settings()) {
    const em::AutoUpdateSettingsProto& au_settings_proto =
        policy.auto_update_settings();
    if (au_settings_proto.has_update_disabled()) {
      new_values_cache->SetBoolean(kUpdateDisabled,
                                   au_settings_proto.update_disabled());
    }

    if (au_settings_proto.has_target_version_prefix()) {
      new_values_cache->SetString(kTargetVersionPrefix,
                                  au_settings_proto.target_version_prefix());
    }

    const RepeatedField<int>& allowed_connection_types =
        au_settings_proto.allowed_connection_types();
    std::unique_ptr<base::ListValue> list(new base::ListValue());
    for (RepeatedField<int>::const_iterator i(allowed_connection_types.begin());
         i != allowed_connection_types.end(); ++i) {
      list->AppendInteger(*i);
    }
    if (!list->empty()) {
      new_values_cache->SetValue(kAllowedConnectionTypesForUpdate,
                                 std::move(list));
    }

    if (au_settings_proto.has_disallowed_time_intervals()) {
      std::unique_ptr<base::Value> decoded_intervals =
          DecodeJsonStringAndDropUnknownBySchema(
              au_settings_proto.disallowed_time_intervals(),
              "DeviceAutoUpdateTimeRestrictions");
      if (decoded_intervals) {
        new_values_cache->SetValue(kDeviceAutoUpdateTimeRestrictions,
                                   std::move(decoded_intervals));
      }
    }
  }
}

void DecodeReportingPolicies(
    const em::ChromeDeviceSettingsProto& policy,
    PrefValueMap* new_values_cache) {
  if (policy.has_device_reporting()) {
    const em::DeviceReportingProto& reporting_policy =
        policy.device_reporting();
    if (reporting_policy.has_report_version_info()) {
      new_values_cache->SetBoolean(
          kReportDeviceVersionInfo,
          reporting_policy.report_version_info());
    }
    if (reporting_policy.has_report_activity_times()) {
      new_values_cache->SetBoolean(
          kReportDeviceActivityTimes,
          reporting_policy.report_activity_times());
    }
    if (reporting_policy.has_report_boot_mode()) {
      new_values_cache->SetBoolean(
          kReportDeviceBootMode,
          reporting_policy.report_boot_mode());
    }
    if (reporting_policy.has_report_network_interfaces()) {
      new_values_cache->SetBoolean(
          kReportDeviceNetworkInterfaces,
          reporting_policy.report_network_interfaces());
    }
    if (reporting_policy.has_report_users()) {
      new_values_cache->SetBoolean(
          kReportDeviceUsers,
          reporting_policy.report_users());
    }
    if (reporting_policy.has_report_hardware_status()) {
      new_values_cache->SetBoolean(
          kReportDeviceHardwareStatus,
          reporting_policy.report_hardware_status());
    }
    if (reporting_policy.has_report_session_status()) {
      new_values_cache->SetBoolean(
          kReportDeviceSessionStatus,
          reporting_policy.report_session_status());
    }
    if (reporting_policy.has_report_os_update_status()) {
      new_values_cache->SetBoolean(kReportOsUpdateStatus,
                                   reporting_policy.report_os_update_status());
    }
    if (reporting_policy.has_report_running_kiosk_app()) {
      new_values_cache->SetBoolean(kReportRunningKioskApp,
                                   reporting_policy.report_running_kiosk_app());
    }
    if (reporting_policy.has_device_status_frequency()) {
      new_values_cache->SetInteger(
          kReportUploadFrequency,
          reporting_policy.device_status_frequency());
    }
  }
}

void DecodeHeartbeatPolicies(
    const em::ChromeDeviceSettingsProto& policy,
    PrefValueMap* new_values_cache) {
  if (!policy.has_device_heartbeat_settings())
    return;

  const em::DeviceHeartbeatSettingsProto& heartbeat_policy =
      policy.device_heartbeat_settings();
  if (heartbeat_policy.has_heartbeat_enabled()) {
    new_values_cache->SetBoolean(
        kHeartbeatEnabled,
        heartbeat_policy.heartbeat_enabled());
  }
  if (heartbeat_policy.has_heartbeat_frequency()) {
    new_values_cache->SetInteger(
        kHeartbeatFrequency,
        heartbeat_policy.heartbeat_frequency());
  }
}

void DecodeGenericPolicies(const em::ChromeDeviceSettingsProto& policy,
                           bool is_enterprise_managed,
                           PrefValueMap* new_values_cache) {
  if (policy.has_metrics_enabled() &&
      policy.metrics_enabled().has_metrics_enabled()) {
    new_values_cache->SetBoolean(kStatsReportingPref,
                                 policy.metrics_enabled().metrics_enabled());
  } else {
    // If the policy is missing, default to reporting enabled on enterprise-
    // enrolled devices, c.f. crbug/456186.
    new_values_cache->SetBoolean(kStatsReportingPref, is_enterprise_managed);
  }

  if (!policy.has_release_channel() ||
      !policy.release_channel().has_release_channel()) {
    // Default to an invalid channel (will be ignored).
    new_values_cache->SetString(kReleaseChannel, "");
  } else {
    new_values_cache->SetString(kReleaseChannel,
                                policy.release_channel().release_channel());
  }

  new_values_cache->SetBoolean(
      kReleaseChannelDelegated,
      policy.has_release_channel() &&
          policy.release_channel().has_release_channel_delegated() &&
          policy.release_channel().release_channel_delegated());

  if (policy.has_system_timezone()) {
    if (policy.system_timezone().has_timezone()) {
      new_values_cache->SetString(
          kSystemTimezonePolicy,
          policy.system_timezone().timezone());
    }
  }

  if (policy.has_use_24hour_clock()) {
    if (policy.use_24hour_clock().has_use_24hour_clock()) {
      new_values_cache->SetBoolean(
          kSystemUse24HourClock, policy.use_24hour_clock().use_24hour_clock());
    }
  }

  if (policy.has_allow_redeem_offers() &&
      policy.allow_redeem_offers().has_allow_redeem_offers()) {
    new_values_cache->SetBoolean(
        kAllowRedeemChromeOsRegistrationOffers,
        policy.allow_redeem_offers().allow_redeem_offers());
  } else {
    new_values_cache->SetBoolean(
        kAllowRedeemChromeOsRegistrationOffers,
        true);
  }

  if (policy.has_variations_parameter()) {
    new_values_cache->SetString(
        kVariationsRestrictParameter,
        policy.variations_parameter().parameter());
  }

  new_values_cache->SetBoolean(
      kDeviceAttestationEnabled,
      policy.attestation_settings().attestation_enabled());

  if (policy.has_attestation_settings() &&
      policy.attestation_settings().has_content_protection_enabled()) {
    new_values_cache->SetBoolean(
        kAttestationForContentProtectionEnabled,
        policy.attestation_settings().content_protection_enabled());
  } else {
    new_values_cache->SetBoolean(kAttestationForContentProtectionEnabled, true);
  }

  if (policy.has_extension_cache_size() &&
      policy.extension_cache_size().has_extension_cache_size()) {
    new_values_cache->SetInteger(
        kExtensionCacheSize,
        policy.extension_cache_size().extension_cache_size());
  }

  if (policy.has_display_rotation_default() &&
      policy.display_rotation_default().has_display_rotation_default()) {
    new_values_cache->SetInteger(
        kDisplayRotationDefault,
        policy.display_rotation_default().display_rotation_default());
  }

  if (policy.has_allow_bluetooth() &&
      policy.allow_bluetooth().has_allow_bluetooth()) {
    new_values_cache->SetBoolean(kAllowBluetooth,
                                 policy.allow_bluetooth().allow_bluetooth());
  } else {
    new_values_cache->SetBoolean(kAllowBluetooth, true);
  }

  if (policy.has_quirks_download_enabled() &&
      policy.quirks_download_enabled().has_quirks_download_enabled()) {
    new_values_cache->SetBoolean(
        kDeviceQuirksDownloadEnabled,
        policy.quirks_download_enabled().quirks_download_enabled());
  }

  if (policy.has_device_wallpaper_image() &&
      policy.device_wallpaper_image().has_device_wallpaper_image()) {
    const std::string& wallpaper_policy(
        policy.device_wallpaper_image().device_wallpaper_image());
    std::unique_ptr<base::DictionaryValue> dict_val =
        base::DictionaryValue::From(base::JSONReader::Read(wallpaper_policy));
    if (dict_val) {
      new_values_cache->SetValue(kDeviceWallpaperImage, std::move(dict_val));
    } else {
      SYSLOG(ERROR) << "Value of wallpaper policy has invalid format: "
                    << wallpaper_policy;
    }
  }

  if (policy.has_device_off_hours()) {
    auto off_hours_policy = policy::off_hours::ConvertOffHoursProtoToValue(
        policy.device_off_hours());
    if (off_hours_policy)
      new_values_cache->SetValue(kDeviceOffHours, std::move(off_hours_policy));
  }

  if (policy.has_tpm_firmware_update_settings()) {
    new_values_cache->SetValue(kTPMFirmwareUpdateSettings,
                               tpm_firmware_update::DecodeSettingsProto(
                                   policy.tpm_firmware_update_settings()));
  }

  if (policy.has_minimum_required_version()) {
    const em::MinimumRequiredVersionProto& container(
        policy.minimum_required_version());
    if (container.has_chrome_version())
      new_values_cache->SetString(kMinimumRequiredChromeVersion,
                                  container.chrome_version());
  }

  if (policy.has_cast_receiver_name()) {
    const em::CastReceiverNameProto& container(policy.cast_receiver_name());
    if (container.has_name()) {
      new_values_cache->SetValue(
          kCastReceiverName, std::make_unique<base::Value>(container.name()));
    }
  }

  if (policy.has_unaffiliated_arc_allowed()) {
    const em::UnaffiliatedArcAllowedProto& container(
        policy.unaffiliated_arc_allowed());
    if (container.has_unaffiliated_arc_allowed()) {
      new_values_cache->SetValue(
          kUnaffiliatedArcAllowed,
          std::make_unique<base::Value>(container.unaffiliated_arc_allowed()));
    }
  }

  if (policy.has_network_hostname()) {
    const em::NetworkHostnameProto& container(policy.network_hostname());
    if (container.has_device_hostname_template() &&
        !container.device_hostname_template().empty()) {
      new_values_cache->SetString(kDeviceHostnameTemplate,
                                  container.device_hostname_template());
    }
  }

  if (policy.virtual_machines_allowed().has_virtual_machines_allowed()) {
    new_values_cache->SetBoolean(
        kVirtualMachinesAllowed,
        policy.virtual_machines_allowed().virtual_machines_allowed());
  } else {
    // If the policy is missing, default to false on enterprise-enrolled
    // devices.
    if (is_enterprise_managed) {
      new_values_cache->SetBoolean(kVirtualMachinesAllowed, false);
    }
  }
}

void DecodeLogUploadPolicies(const em::ChromeDeviceSettingsProto& policy,
                             PrefValueMap* new_values_cache) {
  if (!policy.has_device_log_upload_settings())
    return;

  const em::DeviceLogUploadSettingsProto& log_upload_policy =
      policy.device_log_upload_settings();
  if (log_upload_policy.has_system_log_upload_enabled()) {
    new_values_cache->SetBoolean(kSystemLogUploadEnabled,
                                 log_upload_policy.system_log_upload_enabled());
  }
}

void DecodeDeviceState(const em::PolicyData& policy_data,
                       PrefValueMap* new_values_cache) {
  if (!policy_data.has_device_state())
    return;

  const em::DeviceState& device_state = policy_data.device_state();

  if (device_state.device_mode() == em::DeviceState::DEVICE_MODE_DISABLED)
    new_values_cache->SetBoolean(kDeviceDisabled, true);
  if (device_state.has_disabled_state() &&
      device_state.disabled_state().has_message()) {
    new_values_cache->SetString(kDeviceDisabledMessage,
                                device_state.disabled_state().message());
  }
}

}  // namespace

DeviceSettingsProvider::DeviceSettingsProvider(
    const NotifyObserversCallback& notify_cb,
    DeviceSettingsService* device_settings_service)
    : CrosSettingsProvider(notify_cb),
      device_settings_service_(device_settings_service),
      trusted_status_(TEMPORARILY_UNTRUSTED),
      ownership_status_(device_settings_service_->GetOwnershipStatus()),
      store_callback_factory_(this) {
  device_settings_service_->AddObserver(this);
  if (!UpdateFromService()) {
    // Make sure we have at least the cache data immediately.
    RetrieveCachedData();
  }
}

DeviceSettingsProvider::~DeviceSettingsProvider() {
  if (device_settings_service_->GetOwnerSettingsService())
    device_settings_service_->GetOwnerSettingsService()->RemoveObserver(this);
  device_settings_service_->RemoveObserver(this);
}

// static
bool DeviceSettingsProvider::IsDeviceSetting(const std::string& name) {
  const char* const* end = kKnownSettings + arraysize(kKnownSettings);
  return std::find(kKnownSettings, end, name) != end;
}

// static
void DeviceSettingsProvider::DecodePolicies(
    const em::ChromeDeviceSettingsProto& policy,
    PrefValueMap* new_values_cache) {
  bool is_enterprise_managed = InstallAttributes::Get()->IsEnterpriseManaged();

  DecodeLoginPolicies(policy, is_enterprise_managed, new_values_cache);
  DecodeNetworkPolicies(policy, new_values_cache);
  DecodeAutoUpdatePolicies(policy, new_values_cache);
  DecodeReportingPolicies(policy, new_values_cache);
  DecodeHeartbeatPolicies(policy, new_values_cache);
  DecodeGenericPolicies(policy, is_enterprise_managed, new_values_cache);
  DecodeLogUploadPolicies(policy, new_values_cache);
}

void DeviceSettingsProvider::DoSet(const std::string& path,
                                   const base::Value& in_value) {
  // Make sure that either the current user is the device owner or the
  // device doesn't have an owner yet.
  if (!(device_settings_service_->HasPrivateOwnerKey() ||
        ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
    LOG(WARNING) << "Changing settings from non-owner, setting=" << path;

    // Revert UI change.
    NotifyObservers(path);
    return;
  }

  if (!IsDeviceSetting(path)) {
    NOTREACHED() << "Try to set unhandled cros setting " << path;
    return;
  }

  if (device_settings_service_->HasPrivateOwnerKey()) {
    // Directly set setting through OwnerSettingsService.
    ownership::OwnerSettingsService* service =
        device_settings_service_->GetOwnerSettingsService();
    if (!service->Set(path, in_value)) {
      NotifyObservers(path);
      return;
    }
  } else {
    // Temporary store new setting in
    // |device_settings_|. |device_settings_| will be stored on a disk
    // as soon as an ownership of device the will be taken.
    OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
        path, in_value, device_settings_);
    em::PolicyData data;
    data.set_username(device_settings_service_->GetUsername());
    CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));

    // Set the cache to the updated value.
    UpdateValuesCache(data, device_settings_, TEMPORARILY_UNTRUSTED);

    if (!device_settings_cache::Store(data, g_browser_process->local_state())) {
      LOG(ERROR) << "Couldn't store to the temp storage.";
      NotifyObservers(path);
      return;
    }
  }
}

void DeviceSettingsProvider::OwnershipStatusChanged() {
  DeviceSettingsService::OwnershipStatus new_ownership_status =
      device_settings_service_->GetOwnershipStatus();

  if (device_settings_service_->GetOwnerSettingsService())
    device_settings_service_->GetOwnerSettingsService()->AddObserver(this);

  // If the device just became owned, write the settings accumulated in the
  // cache to device settings proper. It is important that writing only happens
  // in this case, as during normal operation, the contents of the cache should
  // never overwrite actual device settings.
  if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
      ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
      device_settings_service_->HasPrivateOwnerKey()) {
    // There shouldn't be any pending writes, since the cache writes are all
    // immediate.
    DCHECK(!store_callback_factory_.HasWeakPtrs());

    trusted_status_ = TEMPORARILY_UNTRUSTED;
    // Apply the locally-accumulated device settings on top of the initial
    // settings from the service and write back the result.
    if (device_settings_service_->device_settings()) {
      em::ChromeDeviceSettingsProto new_settings(
          *device_settings_service_->device_settings());
      new_settings.MergeFrom(device_settings_);
      device_settings_.Swap(&new_settings);
    }

    std::unique_ptr<em::PolicyData> policy(new em::PolicyData());
    policy->set_username(device_settings_service_->GetUsername());
    CHECK(device_settings_.SerializeToString(policy->mutable_policy_value()));
    if (!device_settings_service_->GetOwnerSettingsService()
             ->CommitTentativeDeviceSettings(std::move(policy))) {
      LOG(ERROR) << "Can't store policy";
    }
  }

  ownership_status_ = new_ownership_status;
}

void DeviceSettingsProvider::DeviceSettingsUpdated() {
  if (!store_callback_factory_.HasWeakPtrs())
    UpdateAndProceedStoring();
}

void DeviceSettingsProvider::OnDeviceSettingsServiceShutdown() {
  device_settings_service_ = nullptr;
}

void DeviceSettingsProvider::OnTentativeChangesInPolicy(
    const em::PolicyData& policy_data) {
  em::ChromeDeviceSettingsProto device_settings;
  CHECK(device_settings.ParseFromString(policy_data.policy_value()));
  UpdateValuesCache(policy_data, device_settings, TEMPORARILY_UNTRUSTED);
}

void DeviceSettingsProvider::RetrieveCachedData() {
  em::PolicyData policy_data;
  if (!device_settings_cache::Retrieve(&policy_data,
                                       g_browser_process->local_state()) ||
      !device_settings_.ParseFromString(policy_data.policy_value())) {
    VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
  }

  UpdateValuesCache(policy_data, device_settings_, trusted_status_);
}

void DeviceSettingsProvider::UpdateValuesCache(
    const em::PolicyData& policy_data,
    const em::ChromeDeviceSettingsProto& settings,
    TrustedStatus trusted_status) {
  PrefValueMap new_values_cache;

  // Determine whether device is managed. See PolicyData::management_mode docs
  // for details.
  bool managed = false;
  if (policy_data.has_management_mode()) {
    managed =
        (policy_data.management_mode() == em::PolicyData::ENTERPRISE_MANAGED);
  } else {
    managed = policy_data.has_request_token();
  }

  // If the device is not managed, we set the device owner value.
  if (policy_data.has_username() && !managed)
    new_values_cache.SetString(kDeviceOwner, policy_data.username());

  if (policy_data.has_service_account_identity()) {
    new_values_cache.SetString(kServiceAccountIdentity,
                               policy_data.service_account_identity());
  }

  DecodePolicies(settings, &new_values_cache);
  DecodeDeviceState(policy_data, &new_values_cache);

  // Collect all notifications but send them only after we have swapped the
  // cache so that if somebody actually reads the cache will be already valid.
  std::vector<std::string> notifications;
  // Go through the new values and verify in the old ones.
  auto iter = new_values_cache.begin();
  for (; iter != new_values_cache.end(); ++iter) {
    const base::Value* old_value;
    if (!values_cache_.GetValue(iter->first, &old_value) ||
        !old_value->Equals(iter->second.get())) {
      notifications.push_back(iter->first);
    }
  }
  // Now check for values that have been removed from the policy blob.
  for (iter = values_cache_.begin(); iter != values_cache_.end(); ++iter) {
    const base::Value* value;
    if (!new_values_cache.GetValue(iter->first, &value))
      notifications.push_back(iter->first);
  }
  // Swap and notify.
  values_cache_.Swap(&new_values_cache);
  trusted_status_ = trusted_status;
  for (size_t i = 0; i < notifications.size(); ++i)
    NotifyObservers(notifications[i]);
}

bool DeviceSettingsProvider::MitigateMissingPolicy() {
  // First check if the device has been owned already and if not exit
  // immediately.
  if (InstallAttributes::Get()->GetMode() != policy::DEVICE_MODE_CONSUMER)
    return false;

  // If we are here the policy file were corrupted or missing. This can happen
  // because we are migrating Pre R11 device to the new secure policies or there
  // was an attempt to circumvent policy system. In this case we should populate
  // the policy cache with "safe-mode" defaults which should allow the owner to
  // log in but lock the device for anyone else until the policy blob has been
  // recreated by the session manager.
  LOG(ERROR) << "Corruption of the policy data has been detected."
             << "Switching to \"safe-mode\" policies until the owner logs in "
             << "to regenerate the policy data.";

  device_settings_.Clear();
  device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
  device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
  em::PolicyData empty_policy_data;
  UpdateValuesCache(empty_policy_data, device_settings_, TRUSTED);
  values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);

  return true;
}

const base::Value* DeviceSettingsProvider::Get(const std::string& path) const {
  if (IsDeviceSetting(path)) {
    const base::Value* value;
    if (values_cache_.GetValue(path, &value))
      return value;
  } else {
    NOTREACHED() << "Trying to get non cros setting.";
  }

  return NULL;
}

DeviceSettingsProvider::TrustedStatus
    DeviceSettingsProvider::PrepareTrustedValues(const base::Closure& cb) {
  TrustedStatus status = RequestTrustedEntity();
  if (status == TEMPORARILY_UNTRUSTED && !cb.is_null())
    callbacks_.push_back(cb);
  return status;
}

bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
  return IsDeviceSetting(path);
}

DeviceSettingsProvider::TrustedStatus
    DeviceSettingsProvider::RequestTrustedEntity() {
  if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
    return TRUSTED;
  return trusted_status_;
}

void DeviceSettingsProvider::UpdateAndProceedStoring() {
  // Re-sync the cache from the service.
  UpdateFromService();
}

bool DeviceSettingsProvider::UpdateFromService() {
  bool settings_loaded = false;
  switch (device_settings_service_->status()) {
    case DeviceSettingsService::STORE_SUCCESS: {
      const em::PolicyData* policy_data =
          device_settings_service_->policy_data();
      const em::ChromeDeviceSettingsProto* device_settings =
          device_settings_service_->device_settings();
      if (policy_data && device_settings) {
        if (!device_settings_cache::Store(*policy_data,
                                          g_browser_process->local_state())) {
          LOG(ERROR) << "Couldn't update the local state cache.";
        }
        UpdateValuesCache(*policy_data, *device_settings, TRUSTED);
        device_settings_ = *device_settings;

        settings_loaded = true;
      } else {
        // Initial policy load is still pending.
        trusted_status_ = TEMPORARILY_UNTRUSTED;
      }
      break;
    }
    case DeviceSettingsService::STORE_NO_POLICY:
      if (MitigateMissingPolicy())
        break;
      FALLTHROUGH;
    case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
      VLOG(1) << "No policies present yet, will use the temp storage.";
      trusted_status_ = PERMANENTLY_UNTRUSTED;
      break;
    case DeviceSettingsService::STORE_VALIDATION_ERROR:
    case DeviceSettingsService::STORE_INVALID_POLICY:
    case DeviceSettingsService::STORE_OPERATION_FAILED:
      LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
                 << device_settings_service_->status();
      trusted_status_ = PERMANENTLY_UNTRUSTED;
      break;
  }

  // Notify the observers we are done.
  std::vector<base::Closure> callbacks;
  callbacks.swap(callbacks_);
  for (size_t i = 0; i < callbacks.size(); ++i)
    callbacks[i].Run();

  return settings_loaded;
}

}  // namespace chromeos
