Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(477)

Unified Diff: components/policy/core/common/cloud/cloud_policy_client.cc

Issue 885653007: Modify CloudPolicyClient to support multiple concurrent requests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More review feedback Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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() {

Powered by Google App Engine
This is Rietveld 408576698