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 21namespace policy { 22 23namespace { 24 25const char kLidCloseAction[] = "LidCloseAction"; 26const char kUserActivityScreenDimDelayScale[] = 27 "UserActivityScreenDimDelayScale"; 28 29const char kActionSuspend[] = "Suspend"; 30const char kActionLogout[] = "Logout"; 31const char kActionShutdown[] = "Shutdown"; 32const char kActionDoNothing[] = "DoNothing"; 33 34scoped_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. 58void 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. 74void 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 88LoginProfilePolicyProvider::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 95LoginProfilePolicyProvider::~LoginProfilePolicyProvider() { 96} 97 98void 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 105void LoginProfilePolicyProvider::Shutdown() { 106 device_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this); 107 weak_factory_.InvalidateWeakPtrs(); 108 ConfigurationPolicyProvider::Shutdown(); 109} 110 111void 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 119void 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 126void LoginProfilePolicyProvider::OnPolicyServiceInitialized( 127 PolicyDomain domain) { 128 if (domain == POLICY_DOMAIN_CHROME) 129 UpdateFromDevicePolicy(); 130} 131 132void LoginProfilePolicyProvider::OnDevicePolicyRefreshDone() { 133 waiting_for_device_policy_refresh_ = false; 134 UpdateFromDevicePolicy(); 135} 136 137void 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