Roll src/third_party/WebKit 3aea697:d9c6159 (svn 201973:201974)
[chromium-blink-merge.git] / components / policy / core / common / cloud / cloud_policy_client.cc
blobf222db191d81fa3b119ed3691f9019c15fdee3ff
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_client.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/guid.h"
10 #include "base/logging.h"
11 #include "base/stl_util.h"
12 #include "components/policy/core/common/cloud/device_management_service.h"
13 #include "google_apis/gaia/gaia_constants.h"
14 #include "google_apis/gaia/gaia_urls.h"
15 #include "net/url_request/url_request_context_getter.h"
17 namespace em = enterprise_management;
19 namespace policy {
21 namespace {
23 // Translates the DeviceRegisterResponse::DeviceMode |mode| to the enum used
24 // internally to represent different device modes.
25 DeviceMode TranslateProtobufDeviceMode(
26 em::DeviceRegisterResponse::DeviceMode mode) {
27 switch (mode) {
28 case em::DeviceRegisterResponse::ENTERPRISE:
29 return DEVICE_MODE_ENTERPRISE;
30 case em::DeviceRegisterResponse::RETAIL:
31 return DEVICE_MODE_LEGACY_RETAIL_MODE;
33 LOG(ERROR) << "Unknown enrollment mode in registration response: " << mode;
34 return DEVICE_MODE_NOT_SET;
37 bool IsChromePolicy(const std::string& type) {
38 return type == dm_protocol::kChromeDevicePolicyType ||
39 type == dm_protocol::kChromeUserPolicyType;
42 } // namespace
44 CloudPolicyClient::Observer::~Observer() {}
46 void CloudPolicyClient::Observer::OnRobotAuthCodesFetched(
47 CloudPolicyClient* client) {}
49 CloudPolicyClient::CloudPolicyClient(
50 const std::string& machine_id,
51 const std::string& machine_model,
52 const std::string& verification_key_hash,
53 DeviceManagementService* service,
54 scoped_refptr<net::URLRequestContextGetter> request_context)
55 : machine_id_(machine_id),
56 machine_model_(machine_model),
57 verification_key_hash_(verification_key_hash),
58 device_mode_(DEVICE_MODE_NOT_SET),
59 submit_machine_id_(false),
60 public_key_version_(-1),
61 public_key_version_valid_(false),
62 invalidation_version_(0),
63 fetched_invalidation_version_(0),
64 service_(service), // Can be null for unit tests.
65 status_(DM_STATUS_SUCCESS),
66 request_context_(request_context) {
69 CloudPolicyClient::~CloudPolicyClient() {
70 STLDeleteValues(&responses_);
73 void CloudPolicyClient::SetupRegistration(const std::string& dm_token,
74 const std::string& client_id) {
75 DCHECK(!dm_token.empty());
76 DCHECK(!client_id.empty());
77 DCHECK(!is_registered());
79 dm_token_ = dm_token;
80 client_id_ = client_id;
81 request_jobs_.clear();
82 policy_fetch_request_job_.reset();
83 STLDeleteValues(&responses_);
85 NotifyRegistrationStateChanged();
88 void CloudPolicyClient::Register(em::DeviceRegisterRequest::Type type,
89 em::DeviceRegisterRequest::Flavor flavor,
90 const std::string& auth_token,
91 const std::string& client_id,
92 const std::string& requisition,
93 const std::string& current_state_key) {
94 DCHECK(service_);
95 DCHECK(!auth_token.empty());
96 DCHECK(!is_registered());
98 if (client_id.empty()) {
99 // Generate a new client ID. This is intentionally done on each new
100 // registration request in order to preserve privacy. Reusing IDs would mean
101 // the server could track clients by their registration attempts.
102 client_id_ = base::GenerateGUID();
103 } else {
104 client_id_ = client_id;
107 policy_fetch_request_job_.reset(
108 service_->CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION,
109 GetRequestContext()));
110 policy_fetch_request_job_->SetOAuthToken(auth_token);
111 policy_fetch_request_job_->SetClientID(client_id_);
113 em::DeviceRegisterRequest* request =
114 policy_fetch_request_job_->GetRequest()->mutable_register_request();
115 if (!client_id.empty())
116 request->set_reregister(true);
117 request->set_type(type);
118 if (!machine_id_.empty())
119 request->set_machine_id(machine_id_);
120 if (!machine_model_.empty())
121 request->set_machine_model(machine_model_);
122 if (!requisition.empty())
123 request->set_requisition(requisition);
124 if (!current_state_key.empty())
125 request->set_server_backed_state_key(current_state_key);
126 request->set_flavor(flavor);
128 policy_fetch_request_job_->SetRetryCallback(
129 base::Bind(&CloudPolicyClient::OnRetryRegister, base::Unretained(this)));
131 policy_fetch_request_job_->Start(
132 base::Bind(&CloudPolicyClient::OnRegisterCompleted,
133 base::Unretained(this)));
136 void CloudPolicyClient::SetInvalidationInfo(
137 int64 version,
138 const std::string& payload) {
139 invalidation_version_ = version;
140 invalidation_payload_ = payload;
143 void CloudPolicyClient::FetchPolicy() {
144 CHECK(is_registered());
145 CHECK(!types_to_fetch_.empty());
147 policy_fetch_request_job_.reset(
148 service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
149 GetRequestContext()));
150 policy_fetch_request_job_->SetDMToken(dm_token_);
151 policy_fetch_request_job_->SetClientID(client_id_);
153 em::DeviceManagementRequest* request =
154 policy_fetch_request_job_->GetRequest();
156 // Build policy fetch requests.
157 em::DevicePolicyRequest* policy_request = request->mutable_policy_request();
158 for (const auto& type_to_fetch : types_to_fetch_) {
159 em::PolicyFetchRequest* fetch_request = policy_request->add_request();
160 fetch_request->set_policy_type(type_to_fetch.first);
161 if (!type_to_fetch.second.empty())
162 fetch_request->set_settings_entity_id(type_to_fetch.second);
164 // Request signed policy blobs to help prevent tampering on the client.
165 fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA);
166 if (public_key_version_valid_)
167 fetch_request->set_public_key_version(public_key_version_);
169 if (!verification_key_hash_.empty())
170 fetch_request->set_verification_key_hash(verification_key_hash_);
172 // These fields are included only in requests for chrome policy.
173 if (IsChromePolicy(type_to_fetch.first)) {
174 if (submit_machine_id_ && !machine_id_.empty())
175 fetch_request->set_machine_id(machine_id_);
176 if (!last_policy_timestamp_.is_null()) {
177 base::TimeDelta timestamp(
178 last_policy_timestamp_ - base::Time::UnixEpoch());
179 fetch_request->set_timestamp(timestamp.InMilliseconds());
181 if (!invalidation_payload_.empty()) {
182 fetch_request->set_invalidation_version(invalidation_version_);
183 fetch_request->set_invalidation_payload(invalidation_payload_);
188 // Add device state keys.
189 if (!state_keys_to_upload_.empty()) {
190 em::DeviceStateKeyUpdateRequest* key_update_request =
191 request->mutable_device_state_key_update_request();
192 for (std::vector<std::string>::const_iterator key(
193 state_keys_to_upload_.begin());
194 key != state_keys_to_upload_.end();
195 ++key) {
196 key_update_request->add_server_backed_state_key(*key);
200 // Set the fetched invalidation version to the latest invalidation version
201 // since it is now the invalidation version used for the latest fetch.
202 fetched_invalidation_version_ = invalidation_version_;
204 // Fire the job.
205 policy_fetch_request_job_->Start(
206 base::Bind(&CloudPolicyClient::OnPolicyFetchCompleted,
207 base::Unretained(this)));
210 void CloudPolicyClient::FetchRobotAuthCodes(const std::string& auth_token) {
211 CHECK(is_registered());
212 DCHECK(!auth_token.empty());
214 policy_fetch_request_job_.reset(service_->CreateJob(
215 DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH,
216 GetRequestContext()));
217 // The credentials of a domain user are needed in order to mint a new OAuth2
218 // authorization token for the robot account.
219 policy_fetch_request_job_->SetOAuthToken(auth_token);
220 policy_fetch_request_job_->SetDMToken(dm_token_);
221 policy_fetch_request_job_->SetClientID(client_id_);
223 em::DeviceServiceApiAccessRequest* request =
224 policy_fetch_request_job_->GetRequest()->
225 mutable_service_api_access_request();
226 request->set_oauth2_client_id(
227 GaiaUrls::GetInstance()->oauth2_chrome_client_id());
228 request->add_auth_scope(GaiaConstants::kAnyApiOAuth2Scope);
230 policy_fetch_request_job_->Start(
231 base::Bind(&CloudPolicyClient::OnFetchRobotAuthCodesCompleted,
232 base::Unretained(this)));
235 void CloudPolicyClient::Unregister() {
236 DCHECK(service_);
237 policy_fetch_request_job_.reset(
238 service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION,
239 GetRequestContext()));
240 policy_fetch_request_job_->SetDMToken(dm_token_);
241 policy_fetch_request_job_->SetClientID(client_id_);
242 policy_fetch_request_job_->GetRequest()->mutable_unregister_request();
243 policy_fetch_request_job_->Start(
244 base::Bind(&CloudPolicyClient::OnUnregisterCompleted,
245 base::Unretained(this)));
248 void CloudPolicyClient::UploadCertificate(
249 const std::string& certificate_data,
250 const CloudPolicyClient::StatusCallback& callback) {
251 CHECK(is_registered());
252 scoped_ptr<DeviceManagementRequestJob> request_job(
253 service_->CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_CERTIFICATE,
254 GetRequestContext()));
255 request_job->SetDMToken(dm_token_);
256 request_job->SetClientID(client_id_);
258 em::DeviceManagementRequest* request = request_job->GetRequest();
259 request->mutable_cert_upload_request()->set_device_certificate(
260 certificate_data);
262 const DeviceManagementRequestJob::Callback job_callback =
263 base::Bind(&CloudPolicyClient::OnCertificateUploadCompleted,
264 base::Unretained(this), request_job.get(), callback);
266 request_jobs_.push_back(request_job.Pass());
267 request_jobs_.back()->Start(job_callback);
270 void CloudPolicyClient::UploadDeviceStatus(
271 const em::DeviceStatusReportRequest* device_status,
272 const em::SessionStatusReportRequest* session_status,
273 const CloudPolicyClient::StatusCallback& callback) {
274 CHECK(is_registered());
275 // Should pass in at least one type of status.
276 DCHECK(device_status || session_status);
277 scoped_ptr<DeviceManagementRequestJob> request_job(
278 service_->CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_STATUS,
279 GetRequestContext()));
280 request_job->SetDMToken(dm_token_);
281 request_job->SetClientID(client_id_);
283 em::DeviceManagementRequest* request = request_job->GetRequest();
284 if (device_status)
285 *request->mutable_device_status_report_request() = *device_status;
286 if (session_status)
287 *request->mutable_session_status_report_request() = *session_status;
289 const DeviceManagementRequestJob::Callback job_callback =
290 base::Bind(&CloudPolicyClient::OnStatusUploadCompleted,
291 base::Unretained(this), request_job.get(), callback);
293 request_jobs_.push_back(request_job.Pass());
294 request_jobs_.back()->Start(job_callback);
297 void CloudPolicyClient::FetchRemoteCommands(
298 scoped_ptr<RemoteCommandJob::UniqueIDType> last_command_id,
299 const std::vector<em::RemoteCommandResult>& command_results,
300 const RemoteCommandCallback& callback) {
301 CHECK(is_registered());
302 scoped_ptr<DeviceManagementRequestJob> request_job(service_->CreateJob(
303 DeviceManagementRequestJob::TYPE_REMOTE_COMMANDS, GetRequestContext()));
305 request_job->SetDMToken(dm_token_);
306 request_job->SetClientID(client_id_);
308 em::DeviceRemoteCommandRequest* const request =
309 request_job->GetRequest()->mutable_remote_command_request();
311 if (last_command_id)
312 request->set_last_command_unique_id(*last_command_id);
314 for (const auto& command_result : command_results)
315 *request->add_command_results() = command_result;
317 const DeviceManagementRequestJob::Callback job_callback =
318 base::Bind(&CloudPolicyClient::OnRemoteCommandsFetched,
319 base::Unretained(this), request_job.get(), callback);
321 request_jobs_.push_back(request_job.Pass());
322 request_jobs_.back()->Start(job_callback);
325 void CloudPolicyClient::GetDeviceAttributeUpdatePermission(
326 const std::string &auth_token,
327 const CloudPolicyClient::StatusCallback& callback) {
328 CHECK(is_registered());
329 DCHECK(!auth_token.empty());
331 scoped_ptr<DeviceManagementRequestJob> request_job(
332 service_->CreateJob(
333 DeviceManagementRequestJob::TYPE_ATTRIBUTE_UPDATE_PERMISSION,
334 GetRequestContext()));
336 request_job->SetOAuthToken(auth_token);
337 request_job->SetClientID(client_id_);
339 request_job->GetRequest()->
340 mutable_device_attribute_update_permission_request();
342 const DeviceManagementRequestJob::Callback job_callback =
343 base::Bind(&CloudPolicyClient::OnDeviceAttributeUpdatePermissionCompleted,
344 base::Unretained(this), request_job.get(), callback);
346 request_jobs_.push_back(request_job.Pass());
347 request_jobs_.back()->Start(job_callback);
350 void CloudPolicyClient::UpdateDeviceAttributes(
351 const std::string& auth_token,
352 const std::string& asset_id,
353 const std::string& location,
354 const CloudPolicyClient::StatusCallback& callback) {
355 CHECK(is_registered());
356 DCHECK(!auth_token.empty());
358 scoped_ptr<DeviceManagementRequestJob> request_job(
359 service_->CreateJob(
360 DeviceManagementRequestJob::TYPE_ATTRIBUTE_UPDATE,
361 GetRequestContext()));
363 request_job->SetOAuthToken(auth_token);
364 request_job->SetClientID(client_id_);
366 em::DeviceAttributeUpdateRequest* request =
367 request_job->GetRequest()->mutable_device_attribute_update_request();
369 request->set_asset_id(asset_id);
370 request->set_location(location);
372 const DeviceManagementRequestJob::Callback job_callback =
373 base::Bind(&CloudPolicyClient::OnDeviceAttributeUpdated,
374 base::Unretained(this), request_job.get(), callback);
376 request_jobs_.push_back(request_job.Pass());
377 request_jobs_.back()->Start(job_callback);
380 void CloudPolicyClient::UpdateGcmId(
381 const std::string& gcm_id,
382 const CloudPolicyClient::StatusCallback& callback) {
383 CHECK(is_registered());
385 scoped_ptr<DeviceManagementRequestJob> request_job(service_->CreateJob(
386 DeviceManagementRequestJob::TYPE_GCM_ID_UPDATE, GetRequestContext()));
388 request_job->SetDMToken(dm_token_);
389 request_job->SetClientID(client_id_);
391 em::GcmIdUpdateRequest* const request =
392 request_job->GetRequest()->mutable_gcm_id_update_request();
394 request->set_gcm_id(gcm_id);
396 const DeviceManagementRequestJob::Callback job_callback =
397 base::Bind(&CloudPolicyClient::OnGcmIdUpdated, base::Unretained(this),
398 request_job.get(), callback);
400 request_jobs_.push_back(request_job.Pass());
401 request_jobs_.back()->Start(job_callback);
404 void CloudPolicyClient::AddObserver(Observer* observer) {
405 observers_.AddObserver(observer);
408 void CloudPolicyClient::RemoveObserver(Observer* observer) {
409 observers_.RemoveObserver(observer);
412 void CloudPolicyClient::AddPolicyTypeToFetch(
413 const std::string& policy_type,
414 const std::string& settings_entity_id) {
415 types_to_fetch_.insert(std::make_pair(policy_type, settings_entity_id));
418 void CloudPolicyClient::RemovePolicyTypeToFetch(
419 const std::string& policy_type,
420 const std::string& settings_entity_id) {
421 types_to_fetch_.erase(std::make_pair(policy_type, settings_entity_id));
424 void CloudPolicyClient::SetStateKeysToUpload(
425 const std::vector<std::string>& keys) {
426 state_keys_to_upload_ = keys;
429 const em::PolicyFetchResponse* CloudPolicyClient::GetPolicyFor(
430 const std::string& policy_type,
431 const std::string& settings_entity_id) const {
432 ResponseMap::const_iterator it =
433 responses_.find(std::make_pair(policy_type, settings_entity_id));
434 return it == responses_.end() ? nullptr : it->second;
437 scoped_refptr<net::URLRequestContextGetter>
438 CloudPolicyClient::GetRequestContext() {
439 return request_context_;
442 int CloudPolicyClient::GetActiveRequestCountForTest() const {
443 return request_jobs_.size();
446 void CloudPolicyClient::OnRetryRegister(DeviceManagementRequestJob* job) {
447 DCHECK_EQ(policy_fetch_request_job_.get(), job);
448 // If the initial request managed to get to the server but the response didn't
449 // arrive at the client then retrying with the same client ID will fail.
450 // Set the re-registration flag so that the server accepts it.
451 // If the server hasn't seen the client ID before then it will also accept
452 // the re-registration.
453 job->GetRequest()->mutable_register_request()->set_reregister(true);
456 void CloudPolicyClient::OnRegisterCompleted(
457 DeviceManagementStatus status,
458 int net_error,
459 const em::DeviceManagementResponse& response) {
460 if (status == DM_STATUS_SUCCESS &&
461 (!response.has_register_response() ||
462 !response.register_response().has_device_management_token())) {
463 LOG(WARNING) << "Invalid registration response.";
464 status = DM_STATUS_RESPONSE_DECODING_ERROR;
467 status_ = status;
468 if (status == DM_STATUS_SUCCESS) {
469 dm_token_ = response.register_response().device_management_token();
470 DVLOG(1) << "Client registration complete - DMToken = " << dm_token_;
472 // Device mode is only relevant for device policy really, it's the
473 // responsibility of the consumer of the field to check validity.
474 device_mode_ = DEVICE_MODE_NOT_SET;
475 if (response.register_response().has_enrollment_type()) {
476 device_mode_ = TranslateProtobufDeviceMode(
477 response.register_response().enrollment_type());
480 NotifyRegistrationStateChanged();
481 } else {
482 NotifyClientError();
486 void CloudPolicyClient::OnFetchRobotAuthCodesCompleted(
487 DeviceManagementStatus status,
488 int net_error,
489 const em::DeviceManagementResponse& response) {
490 if (status == DM_STATUS_SUCCESS &&
491 (!response.has_service_api_access_response())) {
492 LOG(WARNING) << "Invalid service api access response.";
493 status = DM_STATUS_RESPONSE_DECODING_ERROR;
496 status_ = status;
497 if (status == DM_STATUS_SUCCESS) {
498 robot_api_auth_code_ = response.service_api_access_response().auth_code();
499 DVLOG(1) << "Device robot account auth code fetch complete - code = "
500 << robot_api_auth_code_;
502 NotifyRobotAuthCodesFetched();
503 } else {
504 NotifyClientError();
508 void CloudPolicyClient::OnPolicyFetchCompleted(
509 DeviceManagementStatus status,
510 int net_error,
511 const em::DeviceManagementResponse& response) {
512 if (status == DM_STATUS_SUCCESS) {
513 if (!response.has_policy_response() ||
514 response.policy_response().response_size() == 0) {
515 LOG(WARNING) << "Empty policy response.";
516 status = DM_STATUS_RESPONSE_DECODING_ERROR;
520 status_ = status;
521 if (status == DM_STATUS_SUCCESS) {
522 const em::DevicePolicyResponse& policy_response =
523 response.policy_response();
524 STLDeleteValues(&responses_);
525 for (int i = 0; i < policy_response.response_size(); ++i) {
526 const em::PolicyFetchResponse& response = policy_response.response(i);
527 em::PolicyData policy_data;
528 if (!policy_data.ParseFromString(response.policy_data()) ||
529 !policy_data.IsInitialized() ||
530 !policy_data.has_policy_type()) {
531 LOG(WARNING) << "Invalid PolicyData received, ignoring";
532 continue;
534 const std::string& type = policy_data.policy_type();
535 std::string entity_id;
536 if (policy_data.has_settings_entity_id())
537 entity_id = policy_data.settings_entity_id();
538 std::pair<std::string, std::string> key(type, entity_id);
539 if (ContainsKey(responses_, key)) {
540 LOG(WARNING) << "Duplicate PolicyFetchResponse for type: "
541 << type << ", entity: " << entity_id << ", ignoring";
542 continue;
544 responses_[key] = new em::PolicyFetchResponse(response);
546 state_keys_to_upload_.clear();
547 NotifyPolicyFetched();
548 } else {
549 NotifyClientError();
553 void CloudPolicyClient::OnUnregisterCompleted(
554 DeviceManagementStatus status,
555 int net_error,
556 const em::DeviceManagementResponse& response) {
557 if (status == DM_STATUS_SUCCESS && !response.has_unregister_response()) {
558 // Assume unregistration has succeeded either way.
559 LOG(WARNING) << "Empty unregistration response.";
562 status_ = status;
563 if (status == DM_STATUS_SUCCESS) {
564 dm_token_.clear();
565 // Cancel all outstanding jobs.
566 request_jobs_.clear();
567 NotifyRegistrationStateChanged();
568 } else {
569 NotifyClientError();
573 void CloudPolicyClient::OnCertificateUploadCompleted(
574 const DeviceManagementRequestJob* job,
575 const CloudPolicyClient::StatusCallback& callback,
576 DeviceManagementStatus status,
577 int net_error,
578 const enterprise_management::DeviceManagementResponse& response) {
579 bool success = true;
580 status_ = status;
581 if (status != DM_STATUS_SUCCESS) {
582 success = false;
583 NotifyClientError();
584 } else if (!response.has_cert_upload_response()) {
585 LOG(WARNING) << "Empty upload certificate response.";
586 success = false;
588 callback.Run(success);
589 // Must call RemoveJob() last, because it frees |callback|.
590 RemoveJob(job);
593 void CloudPolicyClient::OnDeviceAttributeUpdatePermissionCompleted(
594 const DeviceManagementRequestJob* job,
595 const CloudPolicyClient::StatusCallback& callback,
596 DeviceManagementStatus status,
597 int net_error,
598 const em::DeviceManagementResponse& response) {
599 bool success = false;
601 if (status == DM_STATUS_SUCCESS &&
602 !response.has_device_attribute_update_permission_response()) {
603 LOG(WARNING) << "Invalid device attribute update permission response.";
604 status = DM_STATUS_RESPONSE_DECODING_ERROR;
607 status_ = status;
608 if (status == DM_STATUS_SUCCESS &&
609 response.device_attribute_update_permission_response().has_result() &&
610 response.device_attribute_update_permission_response().result() ==
611 em::DeviceAttributeUpdatePermissionResponse::ATTRIBUTE_UPDATE_ALLOWED) {
612 success = true;
615 callback.Run(success);
616 RemoveJob(job);
619 void CloudPolicyClient::OnDeviceAttributeUpdated(
620 const DeviceManagementRequestJob* job,
621 const CloudPolicyClient::StatusCallback& callback,
622 DeviceManagementStatus status,
623 int net_error,
624 const em::DeviceManagementResponse& response) {
625 bool success = false;
627 if (status == DM_STATUS_SUCCESS &&
628 !response.has_device_attribute_update_response()) {
629 LOG(WARNING) << "Invalid device attribute update response.";
630 status = DM_STATUS_RESPONSE_DECODING_ERROR;
633 status_ = status;
634 if (status == DM_STATUS_SUCCESS &&
635 response.device_attribute_update_response().has_result() &&
636 response.device_attribute_update_response().result() ==
637 em::DeviceAttributeUpdateResponse::ATTRIBUTE_UPDATE_SUCCESS) {
638 success = true;
641 callback.Run(success);
642 RemoveJob(job);
645 void CloudPolicyClient::RemoveJob(const DeviceManagementRequestJob* job) {
646 for (auto it = request_jobs_.begin(); it != request_jobs_.end(); ++it) {
647 if (*it == job) {
648 request_jobs_.erase(it);
649 return;
652 // This job was already deleted from our list, somehow. This shouldn't
653 // happen since deleting the job should cancel the callback.
654 NOTREACHED();
657 void CloudPolicyClient::OnStatusUploadCompleted(
658 const DeviceManagementRequestJob* job,
659 const CloudPolicyClient::StatusCallback& callback,
660 DeviceManagementStatus status,
661 int net_error,
662 const enterprise_management::DeviceManagementResponse& response) {
663 status_ = status;
664 if (status != DM_STATUS_SUCCESS)
665 NotifyClientError();
667 callback.Run(status == DM_STATUS_SUCCESS);
668 // Must call RemoveJob() last, because it frees |callback|.
669 RemoveJob(job);
672 void CloudPolicyClient::OnRemoteCommandsFetched(
673 const DeviceManagementRequestJob* job,
674 const RemoteCommandCallback& callback,
675 DeviceManagementStatus status,
676 int net_error,
677 const enterprise_management::DeviceManagementResponse& response) {
678 std::vector<enterprise_management::RemoteCommand> commands;
679 if (status == DM_STATUS_SUCCESS) {
680 if (response.has_remote_command_response()) {
681 for (const auto& command : response.remote_command_response().commands())
682 commands.push_back(command);
683 } else {
684 status = DM_STATUS_RESPONSE_DECODING_ERROR;
687 callback.Run(status, commands);
688 // Must call RemoveJob() last, because it frees |callback|.
689 RemoveJob(job);
692 void CloudPolicyClient::OnGcmIdUpdated(
693 const DeviceManagementRequestJob* job,
694 const StatusCallback& callback,
695 DeviceManagementStatus status,
696 int net_error,
697 const enterprise_management::DeviceManagementResponse& response) {
698 status_ = status;
699 if (status != DM_STATUS_SUCCESS)
700 NotifyClientError();
702 callback.Run(status == DM_STATUS_SUCCESS);
703 RemoveJob(job);
706 void CloudPolicyClient::NotifyPolicyFetched() {
707 FOR_EACH_OBSERVER(Observer, observers_, OnPolicyFetched(this));
710 void CloudPolicyClient::NotifyRegistrationStateChanged() {
711 FOR_EACH_OBSERVER(Observer, observers_, OnRegistrationStateChanged(this));
714 void CloudPolicyClient::NotifyRobotAuthCodesFetched() {
715 FOR_EACH_OBSERVER(Observer, observers_, OnRobotAuthCodesFetched(this));
718 void CloudPolicyClient::NotifyClientError() {
719 FOR_EACH_OBSERVER(Observer, observers_, OnClientError(this));
722 } // namespace policy