Home | History | Annotate | Download | only in policy
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/policy/login_profile_policy_provider.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.h"
     10 #include "base/callback.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/values.h"
     13 #include "chromeos/dbus/power_policy_controller.h"
     14 #include "components/policy/core/browser/policy_error_map.h"
     15 #include "components/policy/core/common/external_data_fetcher.h"
     16 #include "components/policy/core/common/policy_bundle.h"
     17 #include "components/policy/core/common/policy_map.h"
     18 #include "components/policy/core/common/policy_types.h"
     19 #include "policy/policy_constants.h"
     20 
     21 namespace policy {
     22 
     23 namespace {
     24 
     25 const char kLidCloseAction[] = "LidCloseAction";
     26 const char kUserActivityScreenDimDelayScale[] =
     27     "UserActivityScreenDimDelayScale";
     28 
     29 const char kActionSuspend[] = "Suspend";
     30 const char kActionLogout[] = "Logout";
     31 const char kActionShutdown[]  = "Shutdown";
     32 const char kActionDoNothing[] = "DoNothing";
     33 
     34 scoped_ptr<base::Value> GetAction(const std::string &action) {
     35   if (action == kActionSuspend) {
     36     return scoped_ptr<base::Value>(new base::FundamentalValue(
     37         chromeos::PowerPolicyController::ACTION_SUSPEND));
     38   }
     39   if (action == kActionLogout) {
     40     return scoped_ptr<base::Value>(new base::FundamentalValue(
     41         chromeos::PowerPolicyController::ACTION_STOP_SESSION));
     42   }
     43   if (action == kActionShutdown) {
     44     return scoped_ptr<base::Value>(new base::FundamentalValue(
     45         chromeos::PowerPolicyController::ACTION_SHUT_DOWN));
     46   }
     47   if (action == kActionDoNothing) {
     48     return scoped_ptr<base::Value>(new base::FundamentalValue(
     49         chromeos::PowerPolicyController::ACTION_DO_NOTHING));
     50   }
     51   return scoped_ptr<base::Value>();
     52 }
     53 
     54 
     55 // Applies the value of |device_policy| in |device_policy_map| as the
     56 // recommended value of |user_policy| in |user_policy_map|. If the value of
     57 // |device_policy| is unset, does nothing.
     58 void ApplyDevicePolicyAsRecommendedPolicy(const std::string& device_policy,
     59                                           const std::string& user_policy,
     60                                           const PolicyMap& device_policy_map,
     61                                           PolicyMap* user_policy_map) {
     62   const base::Value* value = device_policy_map.GetValue(device_policy);
     63   if (value) {
     64     user_policy_map->Set(user_policy,
     65                          POLICY_LEVEL_RECOMMENDED,
     66                          POLICY_SCOPE_USER,
     67                          value->DeepCopy(),
     68                          NULL);
     69   }
     70 }
     71 
     72 // Applies |value| as the mandatory value of |user_policy| in |user_policy_map|.
     73 // If |value| is NULL, does nothing.
     74 void ApplyValueAsMandatoryPolicy(const base::Value* value,
     75                                  const std::string& user_policy,
     76                                  PolicyMap* user_policy_map) {
     77   if (value) {
     78     user_policy_map->Set(user_policy,
     79                          POLICY_LEVEL_MANDATORY,
     80                          POLICY_SCOPE_USER,
     81                          value->DeepCopy(),
     82                          NULL);
     83   }
     84 }
     85 
     86 }  // namespace
     87 
     88 LoginProfilePolicyProvider::LoginProfilePolicyProvider(
     89     PolicyService* device_policy_service)
     90     : device_policy_service_(device_policy_service),
     91       waiting_for_device_policy_refresh_(false),
     92       weak_factory_(this) {
     93 }
     94 
     95 LoginProfilePolicyProvider::~LoginProfilePolicyProvider() {
     96 }
     97 
     98 void LoginProfilePolicyProvider::Init(SchemaRegistry* registry) {
     99   ConfigurationPolicyProvider::Init(registry);
    100   device_policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this);
    101   if (device_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME))
    102     UpdateFromDevicePolicy();
    103 }
    104 
    105 void LoginProfilePolicyProvider::Shutdown() {
    106   device_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
    107   weak_factory_.InvalidateWeakPtrs();
    108   ConfigurationPolicyProvider::Shutdown();
    109 }
    110 
    111 void LoginProfilePolicyProvider::RefreshPolicies() {
    112   waiting_for_device_policy_refresh_ = true;
    113   weak_factory_.InvalidateWeakPtrs();
    114   device_policy_service_->RefreshPolicies(base::Bind(
    115       &LoginProfilePolicyProvider::OnDevicePolicyRefreshDone,
    116       weak_factory_.GetWeakPtr()));
    117 }
    118 
    119 void LoginProfilePolicyProvider::OnPolicyUpdated(const PolicyNamespace& ns,
    120                                                  const PolicyMap& previous,
    121                                                  const PolicyMap& current) {
    122   if (ns == PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
    123     UpdateFromDevicePolicy();
    124 }
    125 
    126 void LoginProfilePolicyProvider::OnPolicyServiceInitialized(
    127     PolicyDomain domain) {
    128   if (domain == POLICY_DOMAIN_CHROME)
    129     UpdateFromDevicePolicy();
    130 }
    131 
    132 void LoginProfilePolicyProvider::OnDevicePolicyRefreshDone() {
    133   waiting_for_device_policy_refresh_ = false;
    134   UpdateFromDevicePolicy();
    135 }
    136 
    137 void LoginProfilePolicyProvider::UpdateFromDevicePolicy() {
    138   // If a policy refresh is in progress, wait for it to finish.
    139   if (waiting_for_device_policy_refresh_)
    140     return;
    141 
    142   const PolicyNamespace chrome_namespaces(POLICY_DOMAIN_CHROME, std::string());
    143   const PolicyMap& device_policy_map =
    144       device_policy_service_->GetPolicies(chrome_namespaces);
    145   scoped_ptr<PolicyBundle> bundle(new PolicyBundle);
    146   PolicyMap& user_policy_map = bundle->Get(chrome_namespaces);
    147 
    148   ApplyDevicePolicyAsRecommendedPolicy(
    149       key::kDeviceLoginScreenDefaultLargeCursorEnabled,
    150       key::kLargeCursorEnabled,
    151       device_policy_map, &user_policy_map);
    152   ApplyDevicePolicyAsRecommendedPolicy(
    153       key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled,
    154       key::kSpokenFeedbackEnabled,
    155       device_policy_map, &user_policy_map);
    156   ApplyDevicePolicyAsRecommendedPolicy(
    157       key::kDeviceLoginScreenDefaultHighContrastEnabled,
    158       key::kHighContrastEnabled,
    159       device_policy_map, &user_policy_map);
    160   ApplyDevicePolicyAsRecommendedPolicy(
    161       key::kDeviceLoginScreenDefaultScreenMagnifierType,
    162       key::kScreenMagnifierType,
    163       device_policy_map, &user_policy_map);
    164   ApplyDevicePolicyAsRecommendedPolicy(
    165       key::kDeviceLoginScreenDefaultVirtualKeyboardEnabled,
    166       key::kVirtualKeyboardEnabled,
    167       device_policy_map, &user_policy_map);
    168 
    169   const base::Value* value =
    170       device_policy_map.GetValue(key::kDeviceLoginScreenPowerManagement);
    171   const base::DictionaryValue* dict = NULL;
    172   if (value && value->GetAsDictionary(&dict)) {
    173     scoped_ptr<base::DictionaryValue> policy_value(dict->DeepCopy());
    174     std::string lid_close_action;
    175     base::Value* screen_dim_delay_scale = NULL;
    176 
    177     if (policy_value->GetString(kLidCloseAction, &lid_close_action)) {
    178       scoped_ptr<base::Value> action = GetAction(lid_close_action);
    179       if (action) {
    180         ApplyValueAsMandatoryPolicy(
    181             action.get(), key::kLidCloseAction, &user_policy_map);
    182       }
    183       policy_value->Remove(kLidCloseAction, NULL);
    184     }
    185 
    186     if (policy_value->Get(kUserActivityScreenDimDelayScale,
    187                           &screen_dim_delay_scale)) {
    188       ApplyValueAsMandatoryPolicy(screen_dim_delay_scale,
    189                                   key::kUserActivityScreenDimDelayScale,
    190                                   &user_policy_map);
    191       policy_value->Remove(kUserActivityScreenDimDelayScale, NULL);
    192     }
    193 
    194     // |policy_value| is expected to be a valid value for the
    195     // PowerManagementIdleSettings policy now.
    196     if (!policy_value->empty()) {
    197       ApplyValueAsMandatoryPolicy(policy_value.get(),
    198                                   key::kPowerManagementIdleSettings,
    199                                   &user_policy_map);
    200     }
    201   }
    202 
    203   UpdatePolicy(bundle.Pass());
    204 }
    205 
    206 }  // namespace policy
    207