1// Copyright (c) 2012 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/device_local_account_policy_provider.h" 6 7#include "base/bind.h" 8#include "base/values.h" 9#include "chrome/browser/chromeos/policy/device_local_account.h" 10#include "chrome/browser/chromeos/policy/device_local_account_external_data_manager.h" 11#include "chromeos/dbus/power_policy_controller.h" 12#include "components/policy/core/common/cloud/cloud_policy_core.h" 13#include "components/policy/core/common/cloud/cloud_policy_service.h" 14#include "components/policy/core/common/cloud/component_cloud_policy_service.h" 15#include "components/policy/core/common/policy_bundle.h" 16#include "components/policy/core/common/policy_map.h" 17#include "components/policy/core/common/policy_namespace.h" 18#include "policy/policy_constants.h" 19 20namespace policy { 21 22DeviceLocalAccountPolicyProvider::DeviceLocalAccountPolicyProvider( 23 const std::string& user_id, 24 DeviceLocalAccountPolicyService* service, 25 scoped_ptr<PolicyMap> chrome_policy_overrides) 26 : user_id_(user_id), 27 service_(service), 28 chrome_policy_overrides_(chrome_policy_overrides.Pass()), 29 store_initialized_(false), 30 waiting_for_policy_refresh_(false), 31 weak_factory_(this) { 32 service_->AddObserver(this); 33 UpdateFromBroker(); 34} 35 36DeviceLocalAccountPolicyProvider::~DeviceLocalAccountPolicyProvider() { 37 service_->RemoveObserver(this); 38} 39 40// static 41scoped_ptr<DeviceLocalAccountPolicyProvider> 42DeviceLocalAccountPolicyProvider::Create( 43 const std::string& user_id, 44 DeviceLocalAccountPolicyService* device_local_account_policy_service) { 45 DeviceLocalAccount::Type type; 46 if (!device_local_account_policy_service || 47 !IsDeviceLocalAccountUser(user_id, &type)) { 48 return scoped_ptr<DeviceLocalAccountPolicyProvider>(); 49 } 50 51 scoped_ptr<PolicyMap> chrome_policy_overrides; 52 if (type == DeviceLocalAccount::TYPE_PUBLIC_SESSION) { 53 chrome_policy_overrides.reset(new PolicyMap()); 54 55 // Exit the session when the lid is closed. The default behavior is to 56 // suspend while leaving the session running, which is not desirable for 57 // public sessions. 58 chrome_policy_overrides->Set( 59 key::kLidCloseAction, 60 POLICY_LEVEL_MANDATORY, 61 POLICY_SCOPE_MACHINE, 62 new base::FundamentalValue( 63 chromeos::PowerPolicyController::ACTION_STOP_SESSION), 64 NULL); 65 // Force the |ShelfAutoHideBehavior| policy to |Never|, ensuring that the 66 // ash shelf does not auto-hide. 67 chrome_policy_overrides->Set( 68 key::kShelfAutoHideBehavior, 69 POLICY_LEVEL_MANDATORY, 70 POLICY_SCOPE_MACHINE, 71 new base::StringValue("Never"), 72 NULL); 73 // Force the |ShowLogoutButtonInTray| policy to |true|, ensuring that a big, 74 // red logout button is shown in the ash system tray. 75 chrome_policy_overrides->Set( 76 key::kShowLogoutButtonInTray, 77 POLICY_LEVEL_MANDATORY, 78 POLICY_SCOPE_MACHINE, 79 new base::FundamentalValue(true), 80 NULL); 81 // Force the |FullscreenAllowed| policy to |false|, ensuring that the ash 82 // shelf cannot be hidden by entering fullscreen mode. 83 chrome_policy_overrides->Set( 84 key::kFullscreenAllowed, 85 POLICY_LEVEL_MANDATORY, 86 POLICY_SCOPE_MACHINE, 87 new base::FundamentalValue(false), 88 NULL); 89 } 90 91 scoped_ptr<DeviceLocalAccountPolicyProvider> provider( 92 new DeviceLocalAccountPolicyProvider(user_id, 93 device_local_account_policy_service, 94 chrome_policy_overrides.Pass())); 95 return provider.Pass(); 96} 97 98bool DeviceLocalAccountPolicyProvider::IsInitializationComplete( 99 PolicyDomain domain) const { 100 if (domain == POLICY_DOMAIN_CHROME) 101 return store_initialized_; 102 if (ComponentCloudPolicyService::SupportsDomain(domain) && 103 GetBroker() && GetBroker()->component_policy_service()) { 104 return GetBroker()->component_policy_service()->is_initialized(); 105 } 106 return true; 107} 108 109void DeviceLocalAccountPolicyProvider::RefreshPolicies() { 110 DeviceLocalAccountPolicyBroker* broker = GetBroker(); 111 if (broker && broker->core()->service()) { 112 waiting_for_policy_refresh_ = true; 113 broker->core()->service()->RefreshPolicy( 114 base::Bind(&DeviceLocalAccountPolicyProvider::ReportPolicyRefresh, 115 weak_factory_.GetWeakPtr())); 116 } else { 117 UpdateFromBroker(); 118 } 119} 120 121void DeviceLocalAccountPolicyProvider::OnPolicyUpdated( 122 const std::string& user_id) { 123 if (user_id == user_id_) 124 UpdateFromBroker(); 125} 126 127void DeviceLocalAccountPolicyProvider::OnDeviceLocalAccountsChanged() { 128 UpdateFromBroker(); 129} 130 131DeviceLocalAccountPolicyBroker* DeviceLocalAccountPolicyProvider::GetBroker() 132 const { 133 return service_->GetBrokerForUser(user_id_); 134} 135 136void DeviceLocalAccountPolicyProvider::ReportPolicyRefresh(bool success) { 137 waiting_for_policy_refresh_ = false; 138 UpdateFromBroker(); 139} 140 141void DeviceLocalAccountPolicyProvider::UpdateFromBroker() { 142 DeviceLocalAccountPolicyBroker* broker = GetBroker(); 143 scoped_ptr<PolicyBundle> bundle(new PolicyBundle()); 144 if (broker) { 145 store_initialized_ |= broker->core()->store()->is_initialized(); 146 if (!waiting_for_policy_refresh_) { 147 // Copy policy from the broker. 148 bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 149 .CopyFrom(broker->core()->store()->policy_map()); 150 external_data_manager_ = broker->external_data_manager(); 151 152 if (broker->component_policy_service()) 153 bundle->MergeFrom(broker->component_policy_service()->policy()); 154 } else { 155 // Wait for the refresh to finish. 156 return; 157 } 158 } else { 159 // Keep existing policy, but do send an update. 160 waiting_for_policy_refresh_ = false; 161 weak_factory_.InvalidateWeakPtrs(); 162 bundle->CopyFrom(policies()); 163 } 164 165 // Apply overrides. 166 if (chrome_policy_overrides_) { 167 PolicyMap& chrome_policy = 168 bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); 169 for (PolicyMap::const_iterator it(chrome_policy_overrides_->begin()); 170 it != chrome_policy_overrides_->end(); 171 ++it) { 172 const PolicyMap::Entry& entry = it->second; 173 chrome_policy.Set( 174 it->first, entry.level, entry.scope, entry.value->DeepCopy(), NULL); 175 } 176 } 177 178 UpdatePolicy(bundle.Pass()); 179} 180 181} // namespace policy 182