device_local_account_policy_provider.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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