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
;
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
),
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();
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);
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
) {
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);
85 const em::PolicyFetchResponse
* policy
=
86 client_
->GetPolicyFor(policy_type_
, settings_entity_id_
);
88 if (refresh_state_
!= REFRESH_NONE
)
89 refresh_state_
= REFRESH_POLICY_STORE
;
90 store_
->Store(*policy
, client
->fetched_invalidation_version());
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());
113 base::Time policy_timestamp
;
114 if (policy
&& policy
->has_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());
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();
171 callback
->Run(success
);
175 void CloudPolicyService::UnregisterCompleted(bool 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