| // 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/policy/device_local_account_policy_provider.h" |
| |
| #include "base/bind.h" |
| #include "base/values.h" |
| #include "chrome/browser/chromeos/policy/device_local_account.h" |
| #include "chrome/browser/chromeos/policy/device_local_account_external_data_manager.h" |
| #include "chromeos/dbus/power_policy_controller.h" |
| #include "components/policy/core/common/cloud/cloud_policy_core.h" |
| #include "components/policy/core/common/cloud/cloud_policy_service.h" |
| #include "components/policy/core/common/cloud/component_cloud_policy_service.h" |
| #include "components/policy/core/common/policy_bundle.h" |
| #include "components/policy/core/common/policy_map.h" |
| #include "components/policy/core/common/policy_namespace.h" |
| #include "policy/policy_constants.h" |
| |
| namespace policy { |
| |
| DeviceLocalAccountPolicyProvider::DeviceLocalAccountPolicyProvider( |
| const std::string& user_id, |
| DeviceLocalAccountPolicyService* service, |
| scoped_ptr<PolicyMap> chrome_policy_overrides) |
| : user_id_(user_id), |
| service_(service), |
| chrome_policy_overrides_(chrome_policy_overrides.Pass()), |
| store_initialized_(false), |
| waiting_for_policy_refresh_(false), |
| weak_factory_(this) { |
| service_->AddObserver(this); |
| UpdateFromBroker(); |
| } |
| |
| DeviceLocalAccountPolicyProvider::~DeviceLocalAccountPolicyProvider() { |
| service_->RemoveObserver(this); |
| } |
| |
| // static |
| scoped_ptr<DeviceLocalAccountPolicyProvider> |
| DeviceLocalAccountPolicyProvider::Create( |
| const std::string& user_id, |
| DeviceLocalAccountPolicyService* device_local_account_policy_service) { |
| DeviceLocalAccount::Type type; |
| if (!device_local_account_policy_service || |
| !IsDeviceLocalAccountUser(user_id, &type)) { |
| return scoped_ptr<DeviceLocalAccountPolicyProvider>(); |
| } |
| |
| scoped_ptr<PolicyMap> chrome_policy_overrides; |
| if (type == DeviceLocalAccount::TYPE_PUBLIC_SESSION) { |
| chrome_policy_overrides.reset(new PolicyMap()); |
| |
| // Exit the session when the lid is closed. The default behavior is to |
| // suspend while leaving the session running, which is not desirable for |
| // public sessions. |
| chrome_policy_overrides->Set( |
| key::kLidCloseAction, |
| POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, |
| new base::FundamentalValue( |
| chromeos::PowerPolicyController::ACTION_STOP_SESSION), |
| NULL); |
| // Force the |ShelfAutoHideBehavior| policy to |Never|, ensuring that the |
| // ash shelf does not auto-hide. |
| chrome_policy_overrides->Set( |
| key::kShelfAutoHideBehavior, |
| POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, |
| new base::StringValue("Never"), |
| NULL); |
| // Force the |ShowLogoutButtonInTray| policy to |true|, ensuring that a big, |
| // red logout button is shown in the ash system tray. |
| chrome_policy_overrides->Set( |
| key::kShowLogoutButtonInTray, |
| POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, |
| new base::FundamentalValue(true), |
| NULL); |
| // Force the |FullscreenAllowed| policy to |false|, ensuring that the ash |
| // shelf cannot be hidden by entering fullscreen mode. |
| chrome_policy_overrides->Set( |
| key::kFullscreenAllowed, |
| POLICY_LEVEL_MANDATORY, |
| POLICY_SCOPE_MACHINE, |
| new base::FundamentalValue(false), |
| NULL); |
| } |
| |
| scoped_ptr<DeviceLocalAccountPolicyProvider> provider( |
| new DeviceLocalAccountPolicyProvider(user_id, |
| device_local_account_policy_service, |
| chrome_policy_overrides.Pass())); |
| return provider.Pass(); |
| } |
| |
| bool DeviceLocalAccountPolicyProvider::IsInitializationComplete( |
| PolicyDomain domain) const { |
| if (domain == POLICY_DOMAIN_CHROME) |
| return store_initialized_; |
| if (ComponentCloudPolicyService::SupportsDomain(domain) && |
| GetBroker() && GetBroker()->component_policy_service()) { |
| return GetBroker()->component_policy_service()->is_initialized(); |
| } |
| return true; |
| } |
| |
| void DeviceLocalAccountPolicyProvider::RefreshPolicies() { |
| DeviceLocalAccountPolicyBroker* broker = GetBroker(); |
| if (broker && broker->core()->service()) { |
| waiting_for_policy_refresh_ = true; |
| broker->core()->service()->RefreshPolicy( |
| base::Bind(&DeviceLocalAccountPolicyProvider::ReportPolicyRefresh, |
| weak_factory_.GetWeakPtr())); |
| } else { |
| UpdateFromBroker(); |
| } |
| } |
| |
| void DeviceLocalAccountPolicyProvider::OnPolicyUpdated( |
| const std::string& user_id) { |
| if (user_id == user_id_) |
| UpdateFromBroker(); |
| } |
| |
| void DeviceLocalAccountPolicyProvider::OnDeviceLocalAccountsChanged() { |
| UpdateFromBroker(); |
| } |
| |
| DeviceLocalAccountPolicyBroker* DeviceLocalAccountPolicyProvider::GetBroker() |
| const { |
| return service_->GetBrokerForUser(user_id_); |
| } |
| |
| void DeviceLocalAccountPolicyProvider::ReportPolicyRefresh(bool success) { |
| waiting_for_policy_refresh_ = false; |
| UpdateFromBroker(); |
| } |
| |
| void DeviceLocalAccountPolicyProvider::UpdateFromBroker() { |
| DeviceLocalAccountPolicyBroker* broker = GetBroker(); |
| scoped_ptr<PolicyBundle> bundle(new PolicyBundle()); |
| if (broker) { |
| store_initialized_ |= broker->core()->store()->is_initialized(); |
| if (!waiting_for_policy_refresh_) { |
| // Copy policy from the broker. |
| bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) |
| .CopyFrom(broker->core()->store()->policy_map()); |
| external_data_manager_ = broker->external_data_manager(); |
| |
| if (broker->component_policy_service()) |
| bundle->MergeFrom(broker->component_policy_service()->policy()); |
| } else { |
| // Wait for the refresh to finish. |
| return; |
| } |
| } else { |
| // Keep existing policy, but do send an update. |
| waiting_for_policy_refresh_ = false; |
| weak_factory_.InvalidateWeakPtrs(); |
| bundle->CopyFrom(policies()); |
| } |
| |
| // Apply overrides. |
| if (chrome_policy_overrides_) { |
| PolicyMap& chrome_policy = |
| bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); |
| for (PolicyMap::const_iterator it(chrome_policy_overrides_->begin()); |
| it != chrome_policy_overrides_->end(); |
| ++it) { |
| const PolicyMap::Entry& entry = it->second; |
| chrome_policy.Set( |
| it->first, entry.level, entry.scope, entry.value->DeepCopy(), NULL); |
| } |
| } |
| |
| UpdatePolicy(bundle.Pass()); |
| } |
| |
| } // namespace policy |