Index: components/policy/core/common/cloud/cloud_policy_client.cc |
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc |
index 6f4768afc73f61a1e67b79ef146b8e86b677be02..6f7fbf931c2f28f4de5b44f83d147bf8cd7d8337 100644 |
--- a/components/policy/core/common/cloud/cloud_policy_client.cc |
+++ b/components/policy/core/common/cloud/cloud_policy_client.cc |
@@ -79,7 +79,8 @@ void CloudPolicyClient::SetupRegistration(const std::string& dm_token, |
dm_token_ = dm_token; |
client_id_ = client_id; |
- request_job_.reset(); |
+ request_jobs_.clear(); |
+ policy_fetch_request_job_.reset(); |
STLDeleteValues(&responses_); |
NotifyRegistrationStateChanged(); |
@@ -104,14 +105,14 @@ void CloudPolicyClient::Register(em::DeviceRegisterRequest::Type type, |
client_id_ = client_id; |
} |
- request_job_.reset( |
+ policy_fetch_request_job_.reset( |
service_->CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION, |
GetRequestContext())); |
- request_job_->SetOAuthToken(auth_token); |
- request_job_->SetClientID(client_id_); |
+ policy_fetch_request_job_->SetOAuthToken(auth_token); |
+ policy_fetch_request_job_->SetClientID(client_id_); |
em::DeviceRegisterRequest* request = |
- request_job_->GetRequest()->mutable_register_request(); |
+ policy_fetch_request_job_->GetRequest()->mutable_register_request(); |
if (!client_id.empty()) |
request->set_reregister(true); |
request->set_type(type); |
@@ -125,11 +126,12 @@ void CloudPolicyClient::Register(em::DeviceRegisterRequest::Type type, |
request->set_server_backed_state_key(current_state_key); |
request->set_flavor(flavor); |
- request_job_->SetRetryCallback( |
+ policy_fetch_request_job_->SetRetryCallback( |
base::Bind(&CloudPolicyClient::OnRetryRegister, base::Unretained(this))); |
- request_job_->Start(base::Bind(&CloudPolicyClient::OnRegisterCompleted, |
- base::Unretained(this))); |
+ policy_fetch_request_job_->Start( |
+ base::Bind(&CloudPolicyClient::OnRegisterCompleted, |
+ base::Unretained(this))); |
} |
void CloudPolicyClient::SetInvalidationInfo( |
@@ -143,14 +145,15 @@ void CloudPolicyClient::FetchPolicy() { |
CHECK(is_registered()); |
CHECK(!types_to_fetch_.empty()); |
- request_job_.reset( |
+ policy_fetch_request_job_.reset( |
service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH, |
GetRequestContext())); |
- request_job_->SetDMToken(dm_token_); |
- request_job_->SetClientID(client_id_); |
- request_job_->SetUserAffiliation(user_affiliation_); |
+ policy_fetch_request_job_->SetDMToken(dm_token_); |
+ policy_fetch_request_job_->SetClientID(client_id_); |
+ policy_fetch_request_job_->SetUserAffiliation(user_affiliation_); |
- em::DeviceManagementRequest* request = request_job_->GetRequest(); |
+ em::DeviceManagementRequest* request = |
+ policy_fetch_request_job_->GetRequest(); |
// Build policy fetch requests. |
em::DevicePolicyRequest* policy_request = request->mutable_policy_request(); |
@@ -201,65 +204,70 @@ void CloudPolicyClient::FetchPolicy() { |
fetched_invalidation_version_ = invalidation_version_; |
// Fire the job. |
- request_job_->Start(base::Bind(&CloudPolicyClient::OnPolicyFetchCompleted, |
- base::Unretained(this))); |
+ policy_fetch_request_job_->Start( |
+ base::Bind(&CloudPolicyClient::OnPolicyFetchCompleted, |
+ base::Unretained(this))); |
} |
void CloudPolicyClient::FetchRobotAuthCodes(const std::string& auth_token) { |
CHECK(is_registered()); |
DCHECK(!auth_token.empty()); |
- request_job_.reset(service_->CreateJob( |
+ policy_fetch_request_job_.reset(service_->CreateJob( |
DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH, |
GetRequestContext())); |
// The credentials of a domain user are needed in order to mint a new OAuth2 |
// authorization token for the robot account. |
- request_job_->SetOAuthToken(auth_token); |
- request_job_->SetDMToken(dm_token_); |
- request_job_->SetClientID(client_id_); |
+ policy_fetch_request_job_->SetOAuthToken(auth_token); |
+ policy_fetch_request_job_->SetDMToken(dm_token_); |
+ policy_fetch_request_job_->SetClientID(client_id_); |
em::DeviceServiceApiAccessRequest* request = |
- request_job_->GetRequest()->mutable_service_api_access_request(); |
+ policy_fetch_request_job_->GetRequest()-> |
+ mutable_service_api_access_request(); |
request->set_oauth2_client_id( |
GaiaUrls::GetInstance()->oauth2_chrome_client_id()); |
request->add_auth_scope(GaiaConstants::kAnyApiOAuth2Scope); |
- request_job_->Start( |
+ policy_fetch_request_job_->Start( |
base::Bind(&CloudPolicyClient::OnFetchRobotAuthCodesCompleted, |
base::Unretained(this))); |
} |
void CloudPolicyClient::Unregister() { |
DCHECK(service_); |
- request_job_.reset( |
+ policy_fetch_request_job_.reset( |
service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION, |
GetRequestContext())); |
- request_job_->SetDMToken(dm_token_); |
- request_job_->SetClientID(client_id_); |
- request_job_->GetRequest()->mutable_unregister_request(); |
- request_job_->Start(base::Bind(&CloudPolicyClient::OnUnregisterCompleted, |
- base::Unretained(this))); |
+ policy_fetch_request_job_->SetDMToken(dm_token_); |
+ policy_fetch_request_job_->SetClientID(client_id_); |
+ policy_fetch_request_job_->GetRequest()->mutable_unregister_request(); |
+ policy_fetch_request_job_->Start( |
+ base::Bind(&CloudPolicyClient::OnUnregisterCompleted, |
+ base::Unretained(this))); |
} |
void CloudPolicyClient::UploadCertificate( |
const std::string& certificate_data, |
const CloudPolicyClient::StatusCallback& callback) { |
CHECK(is_registered()); |
- request_job_.reset( |
+ scoped_ptr<DeviceManagementRequestJob> request_job( |
service_->CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_CERTIFICATE, |
GetRequestContext())); |
- request_job_->SetDMToken(dm_token_); |
- request_job_->SetClientID(client_id_); |
+ request_job->SetDMToken(dm_token_); |
+ request_job->SetClientID(client_id_); |
- em::DeviceManagementRequest* request = request_job_->GetRequest(); |
+ em::DeviceManagementRequest* request = request_job->GetRequest(); |
request->mutable_cert_upload_request()->set_device_certificate( |
certificate_data); |
DeviceManagementRequestJob::Callback job_callback = base::Bind( |
&CloudPolicyClient::OnCertificateUploadCompleted, |
base::Unretained(this), |
+ request_job.get(), |
callback); |
- request_job_->Start(job_callback); |
+ request_jobs_.push_back(request_job.Pass()); |
+ request_jobs_.back()->Start(job_callback); |
} |
void CloudPolicyClient::UploadDeviceStatus( |
@@ -269,13 +277,13 @@ void CloudPolicyClient::UploadDeviceStatus( |
CHECK(is_registered()); |
// Should pass in at least one type of status. |
DCHECK(device_status || session_status); |
- request_job_.reset( |
+ scoped_ptr<DeviceManagementRequestJob> request_job( |
service_->CreateJob(DeviceManagementRequestJob::TYPE_UPLOAD_STATUS, |
GetRequestContext())); |
- request_job_->SetDMToken(dm_token_); |
- request_job_->SetClientID(client_id_); |
+ request_job->SetDMToken(dm_token_); |
+ request_job->SetClientID(client_id_); |
- em::DeviceManagementRequest* request = request_job_->GetRequest(); |
+ em::DeviceManagementRequest* request = request_job->GetRequest(); |
if (device_status) |
*request->mutable_device_status_report_request() = *device_status; |
if (session_status) |
@@ -284,12 +292,11 @@ void CloudPolicyClient::UploadDeviceStatus( |
DeviceManagementRequestJob::Callback job_callback = base::Bind( |
&CloudPolicyClient::OnStatusUploadCompleted, |
base::Unretained(this), |
+ request_job.get(), |
callback); |
- // TODO(atwilson): Change CloudPolicyClient to support multiple requests in |
- // parallel, so status upload requests don't get cancelled by things like |
- // policy fetches (http://crbug.com/452563). |
- request_job_->Start(job_callback); |
+ request_jobs_.push_back(request_job.Pass()); |
+ request_jobs_.back()->Start(job_callback); |
} |
void CloudPolicyClient::AddObserver(Observer* observer) { |
@@ -330,8 +337,12 @@ CloudPolicyClient::GetRequestContext() { |
return request_context_; |
} |
+int CloudPolicyClient::GetActiveRequestCountForTest() const { |
+ return request_jobs_.size(); |
+} |
+ |
void CloudPolicyClient::OnRetryRegister(DeviceManagementRequestJob* job) { |
- DCHECK_EQ(request_job_.get(), job); |
+ DCHECK_EQ(policy_fetch_request_job_.get(), job); |
// If the initial request managed to get to the server but the response didn't |
// arrive at the client then retrying with the same client ID will fail. |
// Set the re-registration flag so that the server accepts it. |
@@ -450,6 +461,8 @@ void CloudPolicyClient::OnUnregisterCompleted( |
status_ = status; |
if (status == DM_STATUS_SUCCESS) { |
dm_token_.clear(); |
+ // Cancel all outstanding jobs. |
+ request_jobs_.clear(); |
NotifyRegistrationStateChanged(); |
} else { |
NotifyClientError(); |
@@ -457,26 +470,39 @@ void CloudPolicyClient::OnUnregisterCompleted( |
} |
void CloudPolicyClient::OnCertificateUploadCompleted( |
+ const DeviceManagementRequestJob* job, |
const CloudPolicyClient::StatusCallback& callback, |
DeviceManagementStatus status, |
int net_error, |
const enterprise_management::DeviceManagementResponse& response) { |
- if (status == DM_STATUS_SUCCESS && !response.has_cert_upload_response()) { |
- LOG(WARNING) << "Empty upload certificate response."; |
- callback.Run(false); |
- return; |
- } |
- |
+ bool success = true; |
status_ = status; |
if (status != DM_STATUS_SUCCESS) { |
+ success = false; |
NotifyClientError(); |
- callback.Run(false); |
- return; |
+ } else if (!response.has_cert_upload_response()) { |
+ LOG(WARNING) << "Empty upload certificate response."; |
+ success = false; |
+ } |
+ callback.Run(success); |
+ // Must call RemoveJob() last, because it frees |callback|. |
+ RemoveJob(job); |
+} |
+ |
+void CloudPolicyClient::RemoveJob(const DeviceManagementRequestJob* job) { |
+ for (auto it = request_jobs_.begin(); it != request_jobs_.end(); ++it) { |
+ if (*it == job) { |
+ request_jobs_.erase(it); |
+ return; |
+ } |
} |
- callback.Run(true); |
+ // This job was already deleted from our list, somehow. This shouldn't |
+ // happen since deleting the job should cancel the callback. |
+ NOTREACHED(); |
} |
void CloudPolicyClient::OnStatusUploadCompleted( |
+ const DeviceManagementRequestJob* job, |
const CloudPolicyClient::StatusCallback& callback, |
DeviceManagementStatus status, |
int net_error, |
@@ -486,6 +512,8 @@ void CloudPolicyClient::OnStatusUploadCompleted( |
NotifyClientError(); |
callback.Run(status == DM_STATUS_SUCCESS); |
+ // Must call RemoveJob() last, because it frees |callback|. |
+ RemoveJob(job); |
} |
void CloudPolicyClient::NotifyPolicyFetched() { |