Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / policy / core / common / cloud / cloud_policy_service.cc
blobe79a52534d968b01e613c27a4b1c81686571e44b
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.
5 #include "components/policy/core/common/cloud/cloud_policy_service.h"
7 #include "base/callback.h"
8 #include "base/logging.h"
9 #include "policy/proto/device_management_backend.pb.h"
11 namespace em = enterprise_management;
13 namespace policy {
15 CloudPolicyService::CloudPolicyService(const std::string& policy_type,
16 const std::string& settings_entity_id,
17 CloudPolicyClient* client,
18 CloudPolicyStore* store)
19 : policy_type_(policy_type),
20 settings_entity_id_(settings_entity_id),
21 client_(client),
22 store_(store),
23 refresh_state_(REFRESH_NONE),
24 unregister_state_(UNREGISTER_NONE),
25 initialization_complete_(false) {
26 client_->AddPolicyTypeToFetch(policy_type_, settings_entity_id_);
27 client_->AddObserver(this);
28 store_->AddObserver(this);
30 // Make sure we initialize |client_| from the policy data that might be
31 // already present in |store_|.
32 OnStoreLoaded(store_);
35 CloudPolicyService::~CloudPolicyService() {
36 client_->RemovePolicyTypeToFetch(policy_type_, settings_entity_id_);
37 client_->RemoveObserver(this);
38 store_->RemoveObserver(this);
41 std::string CloudPolicyService::ManagedBy() const {
42 const em::PolicyData* policy = store_->policy();
43 if (policy) {
44 std::string username = policy->username();
45 std::size_t pos = username.find('@');
46 if (pos != std::string::npos)
47 return username.substr(pos + 1);
49 return std::string();
52 void CloudPolicyService::RefreshPolicy(const RefreshPolicyCallback& callback) {
53 // If the client is not registered or is unregistering, bail out.
54 if (!client_->is_registered() || unregister_state_ != UNREGISTER_NONE) {
55 callback.Run(false);
56 return;
59 // Else, trigger a refresh.
60 refresh_callbacks_.push_back(callback);
61 refresh_state_ = REFRESH_POLICY_FETCH;
62 client_->FetchPolicy();
65 void CloudPolicyService::Unregister(const UnregisterCallback& callback) {
66 // Abort all pending refresh requests.
67 if (refresh_state_ != REFRESH_NONE)
68 RefreshCompleted(false);
70 // Abort previous unregister request if any.
71 if (unregister_state_ != UNREGISTER_NONE)
72 UnregisterCompleted(false);
74 unregister_callback_ = callback;
75 unregister_state_ = UNREGISTER_PENDING;
76 client_->Unregister();
79 void CloudPolicyService::OnPolicyFetched(CloudPolicyClient* client) {
80 if (client_->status() != DM_STATUS_SUCCESS) {
81 RefreshCompleted(false);
82 return;
85 const em::PolicyFetchResponse* policy =
86 client_->GetPolicyFor(policy_type_, settings_entity_id_);
87 if (policy) {
88 if (refresh_state_ != REFRESH_NONE)
89 refresh_state_ = REFRESH_POLICY_STORE;
90 store_->Store(*policy, client->fetched_invalidation_version());
91 } else {
92 RefreshCompleted(false);
96 void CloudPolicyService::OnRegistrationStateChanged(CloudPolicyClient* client) {
97 if (unregister_state_ == UNREGISTER_PENDING)
98 UnregisterCompleted(true);
101 void CloudPolicyService::OnClientError(CloudPolicyClient* client) {
102 if (refresh_state_ == REFRESH_POLICY_FETCH)
103 RefreshCompleted(false);
104 if (unregister_state_ == UNREGISTER_PENDING)
105 UnregisterCompleted(false);
108 void CloudPolicyService::OnStoreLoaded(CloudPolicyStore* store) {
109 // Update the client with state from the store.
110 const em::PolicyData* policy(store_->policy());
112 // Timestamp.
113 base::Time policy_timestamp;
114 if (policy && policy->has_timestamp()) {
115 policy_timestamp =
116 base::Time::UnixEpoch() +
117 base::TimeDelta::FromMilliseconds(policy->timestamp());
119 client_->set_last_policy_timestamp(policy_timestamp);
121 // Public key version.
122 if (policy && policy->has_public_key_version())
123 client_->set_public_key_version(policy->public_key_version());
124 else
125 client_->clear_public_key_version();
127 // Whether to submit the machine ID.
128 bool submit_machine_id = false;
129 if (policy && policy->has_valid_serial_number_missing())
130 submit_machine_id = policy->valid_serial_number_missing();
131 client_->set_submit_machine_id(submit_machine_id);
133 // Finally, set up registration if necessary.
134 if (policy && policy->has_request_token() && policy->has_device_id() &&
135 !client_->is_registered()) {
136 DVLOG(1) << "Setting up registration with request token: "
137 << policy->request_token();
138 client_->SetupRegistration(policy->request_token(),
139 policy->device_id());
142 if (refresh_state_ == REFRESH_POLICY_STORE)
143 RefreshCompleted(true);
145 CheckInitializationCompleted();
148 void CloudPolicyService::OnStoreError(CloudPolicyStore* store) {
149 if (refresh_state_ == REFRESH_POLICY_STORE)
150 RefreshCompleted(false);
151 CheckInitializationCompleted();
154 void CloudPolicyService::CheckInitializationCompleted() {
155 if (!IsInitializationComplete() && store_->is_initialized()) {
156 initialization_complete_ = true;
157 FOR_EACH_OBSERVER(Observer, observers_, OnInitializationCompleted(this));
161 void CloudPolicyService::RefreshCompleted(bool success) {
162 // Clear state and |refresh_callbacks_| before actually invoking them, s.t.
163 // triggering new policy fetches behaves as expected.
164 std::vector<RefreshPolicyCallback> callbacks;
165 callbacks.swap(refresh_callbacks_);
166 refresh_state_ = REFRESH_NONE;
168 for (std::vector<RefreshPolicyCallback>::iterator callback(callbacks.begin());
169 callback != callbacks.end();
170 ++callback) {
171 callback->Run(success);
175 void CloudPolicyService::UnregisterCompleted(bool success) {
176 if (!success)
177 LOG(ERROR) << "Unregister request failed.";
179 unregister_state_ = UNREGISTER_NONE;
180 unregister_callback_.Run(success);
181 unregister_callback_ = UnregisterCallback(); // Reset.
184 void CloudPolicyService::AddObserver(Observer* observer) {
185 observers_.AddObserver(observer);
188 void CloudPolicyService::RemoveObserver(Observer* observer) {
189 observers_.RemoveObserver(observer);
192 } // namespace policy