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