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

Unified Diff: chrome/browser/policy/device_management_backend_impl.cc

Issue 5026001: Rework the device management backend implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 10 years, 1 month 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: chrome/browser/policy/device_management_backend_impl.cc
diff --git a/chrome/browser/policy/device_management_backend_impl.cc b/chrome/browser/policy/device_management_backend_impl.cc
index c0e9b0722c28a3d36b50e25cb370772b3846cf70..6e9fdf900a38a435ef972e4ee9e51b0039b65abb 100644
--- a/chrome/browser/policy/device_management_backend_impl.cc
+++ b/chrome/browser/policy/device_management_backend_impl.cc
@@ -5,15 +5,20 @@
#include "chrome/browser/policy/device_management_backend_impl.h"
#include <utility>
+#include <set>
#include <vector>
+#include "base/command_line.h"
+#include "base/lazy_instance.h"
#include "base/stl_util-inl.h"
#include "base/stringprintf.h"
#include "chrome/browser/browser_thread.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "net/base/cookie_monster.h"
#include "net/base/escape.h"
#include "net/base/host_resolver.h"
+#include "net/base/load_flags.h"
#include "net/base/ssl_config_service_defaults.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_layer.h"
@@ -23,6 +28,8 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/chrome_net_log.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
namespace policy {
@@ -43,15 +50,51 @@ const char kServiceValueAgent[] =
const char kServiceTokenAuthHeader[] = "Authorization: GoogleLogin auth=";
const char kDMTokenAuthHeader[] = "Authorization: GoogleDMToken token=";
-} // namespace
+// Helper class for URL query parameter encoding/decoding.
+class URLQueryParameters {
danno 2010/11/16 22:02:56 I am surprised that there is no service to do this
Mattias Nissler (ping if slow) 2010/11/19 17:21:53 I've looked pretty hard and couldn't find anything
+ public:
+ URLQueryParameters() {}
+
+ // Add a query parameter.
+ void Put(const std::string& name, const std::string& value);
+
+ // Produce the query string, taking care of properly encoding and assembling
+ // the names and values.
+ std::string Encode();
+
+ private:
+ typedef std::vector<std::pair<std::string, std::string> > ParameterMap;
+ ParameterMap params_;
+
+ DISALLOW_COPY_AND_ASSIGN(URLQueryParameters);
+};
+
+void URLQueryParameters::Put(const std::string& name,
+ const std::string& value) {
+ params_.push_back(std::make_pair(name, value));
+}
+
+std::string URLQueryParameters::Encode() {
+ std::string result;
+ for (ParameterMap::const_iterator entry(params_.begin());
+ entry != params_.end();
+ ++entry) {
+ if (entry != params_.begin())
+ result += '&';
+ result += EscapeUrlEncodedData(entry->first);
+ result += '=';
+ result += EscapeUrlEncodedData(entry->second);
+ }
+ return result;
+}
// Custom request context implementation that allows to override the user agent,
-// amongst others. Using the default request context is not an option since this
-// service may be constructed before the default request context is created
-// (i.e. before the profile has been loaded).
+// amongst others. Wraps a baseline request context from which we reuse the
+// networking components.
class DeviceManagementBackendRequestContext : public URLRequestContext {
public:
- explicit DeviceManagementBackendRequestContext(IOThread::Globals* io_globals);
+ explicit DeviceManagementBackendRequestContext(
+ URLRequestContext* base_context);
virtual ~DeviceManagementBackendRequestContext();
private:
@@ -61,23 +104,23 @@ class DeviceManagementBackendRequestContext : public URLRequestContext {
};
DeviceManagementBackendRequestContext::DeviceManagementBackendRequestContext(
- IOThread::Globals* io_globals) {
- net_log_ = io_globals->net_log.get();
- host_resolver_ = io_globals->host_resolver.get();
- proxy_service_ = net::ProxyService::CreateDirect();
- ssl_config_service_ = net::SSLConfigService::CreateSystemSSLConfigService();
- http_auth_handler_factory_ =
- net::HttpAuthHandlerFactory::CreateDefault(host_resolver_);
- http_transaction_factory_ =
- net::HttpNetworkLayer::CreateFactory(host_resolver_,
- io_globals->dnsrr_resolver.get(),
- NULL /* ssl_host_info_factory */,
- proxy_service_,
- ssl_config_service_,
- http_auth_handler_factory_,
- NULL /* network_delegate */,
- net_log_);
+ URLRequestContext* base_context) {
+ // Share resolver, proxy service and ssl bits with the baseline context. This
+ // is important so we don't make redundant requests (e.g. when resolving proxy
+ // auto configuration).
+ net_log_ = base_context->net_log();
+ host_resolver_ = base_context->host_resolver();
+ proxy_service_ = base_context->proxy_service();
+ ssl_config_service_ = base_context->ssl_config_service();
+
+ // Share the http session.
+ http_transaction_factory_ = net::HttpNetworkLayer::CreateFactory(
+ base_context->http_transaction_factory()->GetSession());
+
+ // No cookies, please.
cookie_store_ = new net::CookieMonster(NULL, NULL);
+
+ // Initialize these to sane values for our purposes.
user_agent_ = DeviceManagementBackendImpl::GetAgentString();
accept_language_ = "*";
accept_charset_ = "*";
@@ -98,8 +141,9 @@ DeviceManagementBackendRequestContext::GetUserAgent(const GURL& url) const {
class DeviceManagementBackendRequestContextGetter
: public URLRequestContextGetter {
public:
- DeviceManagementBackendRequestContextGetter()
- : io_thread_(g_browser_process->io_thread()) {}
+ DeviceManagementBackendRequestContextGetter(
+ URLRequestContextGetter* base_context_getter)
+ : base_context_getter_(base_context_getter) {}
// URLRequestContextGetter overrides.
virtual URLRequestContext* GetURLRequestContext();
@@ -107,14 +151,17 @@ class DeviceManagementBackendRequestContextGetter
private:
scoped_refptr<URLRequestContext> context_;
- IOThread* io_thread_;
+ scoped_refptr<URLRequestContextGetter> base_context_getter_;
};
URLRequestContext*
DeviceManagementBackendRequestContextGetter::GetURLRequestContext() {
- if (!context_)
- context_ = new DeviceManagementBackendRequestContext(io_thread_->globals());
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (!context_) {
+ context_ = new DeviceManagementBackendRequestContext(
+ base_context_getter_->GetURLRequestContext());
+ }
return context_.get();
}
@@ -124,49 +171,70 @@ DeviceManagementBackendRequestContextGetter::GetIOMessageLoopProxy() const {
return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
}
-// Helper class for URL query parameter encoding/decoding.
-class URLQueryParameters {
+} // namespace
+
+// A wrapper that implements the actual backend interface. It doesn't hold a
+// strong reference to the actual backend implementation object, but tracks
+// whether it's currently available or not and postpones requests accordingly.
+class DeviceManagementBackendProxy : public DeviceManagementBackend {
public:
- URLQueryParameters() {}
+ DeviceManagementBackendProxy(DeviceManagementBackendImpl* backend);
+ virtual ~DeviceManagementBackendProxy();
- // Add a query parameter.
- void Put(const std::string& name, const std::string& value);
+ // Called by the DeviceManagementJob dtor so we can clean up.
markusheintz_ 2010/11/18 12:40:36 typo? "dtor"?
Mattias Nissler (ping if slow) 2010/11/19 17:21:53 It means destructor and is a well-known abbreviati
+ void JobDone(DeviceManagementJob* job);
- // Produce the query string, taking care of properly encoding and assembling
- // the names and values.
- std::string Encode();
+ // Switches all proxies to a different backend instance.
+ static void SwitchBackend(DeviceManagementBackendImpl* backend);
danno 2010/11/16 22:02:56 In practice, there either only the backend NULL or
Mattias Nissler (ping if slow) 2010/11/19 17:21:53 Doesn't apply any longer.
private:
- typedef std::vector<std::pair<std::string, std::string> > ParameterMap;
- ParameterMap params_;
-
- DISALLOW_COPY_AND_ASSIGN(URLQueryParameters);
+ typedef std::set<DeviceManagementJob*> JobSet;
+ typedef std::set<DeviceManagementBackendProxy*> ProxySet;
+
+ // Resets the backend pointer for this proxy.
+ void ResetBackend(DeviceManagementBackendImpl* backend);
+
+ // Add a job to the pending job set and register it with the backend (if
+ // available).
+ void AddJob(DeviceManagementJob* job);
+
+ // GoogleAppsPolicyService overrides.
danno 2010/11/16 22:02:56 Superclass name is the old one.
Mattias Nissler (ping if slow) 2010/11/19 17:21:53 Done.
+ virtual void ProcessRegisterRequest(
+ const std::string& auth_token,
+ const std::string& device_id,
+ const em::DeviceRegisterRequest& request,
+ DeviceRegisterResponseDelegate* response_delegate);
+ virtual void ProcessUnregisterRequest(
+ const std::string& device_management_token,
+ const em::DeviceUnregisterRequest& request,
+ DeviceUnregisterResponseDelegate* response_delegate);
+ virtual void ProcessPolicyRequest(
+ const std::string& device_management_token,
+ const em::DevicePolicyRequest& request,
+ DevicePolicyResponseDelegate* response_delegate);
+
+ static ProxySet& proxies() { return proxies_.Get(); }
+
+ // Keeps track of the jobs currently in flight.
+ JobSet pending_jobs_;
+
+ // The backend implementation pointer.
+ DeviceManagementBackendImpl* backend_instance_;
+
+ // Keeps a list of currently existing proxies.
+ static base::LazyInstance<ProxySet> proxies_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceManagementBackendProxy);
};
-void URLQueryParameters::Put(const std::string& name,
- const std::string& value) {
- params_.push_back(std::make_pair(name, value));
-}
-
-std::string URLQueryParameters::Encode() {
- std::string result;
- for (ParameterMap::const_iterator entry(params_.begin());
- entry != params_.end();
- ++entry) {
- if (entry != params_.begin())
- result += '&';
- result += EscapeUrlEncodedData(entry->first);
- result += '=';
- result += EscapeUrlEncodedData(entry->second);
- }
- return result;
-}
-
-// Wraps common response parsing and handling functionality.
-class ResponseHandler {
+// Represents a job run by the backend. This contains the common code,
+// subclasses provide custom code for actual register, unregister, and policy
+// jobs.
+class DeviceManagementJob {
public:
- ResponseHandler() {}
- virtual ~ResponseHandler() {}
+ virtual ~DeviceManagementJob() {
+ proxy_->JobDone(this);
+ }
// Handles the URL request response.
void HandleResponse(const URLRequestStatus& status,
@@ -174,32 +242,90 @@ class ResponseHandler {
const ResponseCookies& cookies,
const std::string& data);
- // Forwards the given error to the delegate.
- virtual void OnError(DeviceManagementBackend::ErrorCode error) = 0;
+ // Gets the URL to contact.
+ GURL GetURL(const std::string& server_url);
+
+ // Configures the fetcher, setting up payload and headers.
+ void ConfigureRequest(URLFetcher* fetcher);
+
+ protected:
+ // Constructs a device management job running for the given proxy.
+ DeviceManagementJob(DeviceManagementBackendProxy* proxy,
+ const std::string& request_type)
+ : proxy_(proxy) {
+ query_params_.Put(kServiceParamRequest, request_type);
+ query_params_.Put(kServiceParamDeviceType, kServiceValueDeviceType);
+ query_params_.Put(kServiceParamAgent,
+ DeviceManagementBackendImpl::GetAgentString());
+ }
+
+ void SetQueryParam(const std::string& name, const std::string& value) {
+ query_params_.Put(name, value);
+ }
+
+ void SetAuthToken(const std::string& auth_token) {
+ auth_token_ = auth_token;
+ }
+
+ void SetDeviceManagementToken(const std::string& device_management_token) {
+ device_management_token_ = device_management_token;
+ }
+
+ void SetDeviceID(const std::string& device_id) {
+ query_params_.Put(kServiceParamDeviceID, device_id);
+ }
+
+ void SetPayload(const em::DeviceManagementRequest& request) {
+ if (!request.SerializeToString(&payload_)) {
+ NOTREACHED();
+ LOG(ERROR) << "Failed to serialize request.";
+ }
+ }
private:
- // Implemented by subclasses to handle the decoded response.
+ // Implemented by subclasses to handle decoded responses and errors.
virtual void ProcessResponse(
const em::DeviceManagementResponse& response) = 0;
+ virtual void ProcessError(DeviceManagementBackend::ErrorCode error) = 0;
+
+ // The proxy this job is handling a request for.
+ DeviceManagementBackendProxy* proxy_;
+
+ // Query parameters.
+ URLQueryParameters query_params_;
+
+ // Auth token (if applicaple).
+ std::string auth_token_;
+
+ // Device management token (if applicable).
+ std::string device_management_token_;
+
+ // The payload.
+ std::string payload_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceManagementJob);
};
-void ResponseHandler::HandleResponse(const URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
- const std::string& data) {
+void DeviceManagementJob::HandleResponse(const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data) {
+ // Delete ourselves when this is done.
+ scoped_ptr<DeviceManagementJob> scoped_killer(this);
+
if (status.status() != URLRequestStatus::SUCCESS) {
- OnError(DeviceManagementBackend::kErrorRequestFailed);
+ ProcessError(DeviceManagementBackend::kErrorRequestFailed);
danno 2010/11/16 22:02:56 Any particular reason for the name change?
markusheintz_ 2010/11/18 12:40:36 +1 for this questions. Especially since the delega
Mattias Nissler (ping if slow) 2010/11/19 17:21:53 Not any longer, it is a leftover. Changed it back.
return;
}
if (response_code != 200) {
- OnError(DeviceManagementBackend::kErrorHttpStatus);
+ ProcessError(DeviceManagementBackend::kErrorHttpStatus);
return;
}
em::DeviceManagementResponse response;
if (!response.ParseFromString(data)) {
- OnError(DeviceManagementBackend::kErrorResponseDecoding);
+ ProcessError(DeviceManagementBackend::kErrorResponseDecoding);
return;
}
@@ -208,37 +334,57 @@ void ResponseHandler::HandleResponse(const URLRequestStatus& status,
case em::DeviceManagementResponse::SUCCESS:
break;
case em::DeviceManagementResponse::DEVICE_MANAGEMENT_NOT_SUPPORTED:
- OnError(DeviceManagementBackend::kErrorServiceManagementNotSupported);
+ ProcessError(
+ DeviceManagementBackend::kErrorServiceManagementNotSupported);
return;
case em::DeviceManagementResponse::DEVICE_NOT_FOUND:
- OnError(DeviceManagementBackend::kErrorServiceDeviceNotFound);
+ ProcessError(DeviceManagementBackend::kErrorServiceDeviceNotFound);
return;
case em::DeviceManagementResponse::DEVICE_MANAGEMENT_TOKEN_INVALID:
- OnError(DeviceManagementBackend::kErrorServiceManagementTokenInvalid);
+ ProcessError(
+ DeviceManagementBackend::kErrorServiceManagementTokenInvalid);
return;
case em::DeviceManagementResponse::ACTIVATION_PENDING:
- OnError(DeviceManagementBackend::kErrorServiceActivationPending);
+ ProcessError(DeviceManagementBackend::kErrorServiceActivationPending);
return;
default:
// This should be caught by the protobuf decoder.
NOTREACHED();
- OnError(DeviceManagementBackend::kErrorResponseDecoding);
+ ProcessError(DeviceManagementBackend::kErrorResponseDecoding);
return;
}
ProcessResponse(response);
}
-// Handles device registration responses.
-class RegisterResponseHandler : public ResponseHandler {
+GURL DeviceManagementJob::GetURL(const std::string& server_url) {
+ return GURL(server_url + '?' + query_params_.Encode());
+}
+
+void DeviceManagementJob::ConfigureRequest(URLFetcher* fetcher) {
+ fetcher->set_upload_data("application/octet-stream", payload_);
+ std::string extra_headers;
+ if (!auth_token_.empty())
+ extra_headers += kServiceTokenAuthHeader + auth_token_ + "\n";
+ if (!device_management_token_.empty())
+ extra_headers += kDMTokenAuthHeader + device_management_token_ + "\n";
+ fetcher->set_extra_request_headers(extra_headers);
+}
+
+// Handles device registration jobs.
+class DeviceManagementRegisterJob : public DeviceManagementJob {
public:
- RegisterResponseHandler(
- DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate)
- : delegate_(delegate) {}
+ DeviceManagementRegisterJob(
+ DeviceManagementBackendProxy* proxy,
+ const std::string& auth_token,
+ const std::string& device_id,
+ const em::DeviceRegisterRequest& request,
+ DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate);
+ virtual ~DeviceManagementRegisterJob() {}
private:
- // ResponseHandler overrides.
- virtual void OnError(DeviceManagementBackend::ErrorCode error) {
+ // DeviceManagementJob overrides.
+ virtual void ProcessError(DeviceManagementBackend::ErrorCode error) {
delegate_->OnError(error);
}
virtual void ProcessResponse(const em::DeviceManagementResponse& response) {
@@ -246,18 +392,38 @@ class RegisterResponseHandler : public ResponseHandler {
}
DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceManagementRegisterJob);
};
-// Handles device unregister responses.
-class UnregisterResponseHandler : public ResponseHandler {
+DeviceManagementRegisterJob::DeviceManagementRegisterJob(
+ DeviceManagementBackendProxy* proxy,
+ const std::string& auth_token,
+ const std::string& device_id,
+ const em::DeviceRegisterRequest& request,
+ DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate)
+ : DeviceManagementJob(proxy, "register"),
+ delegate_(delegate) {
+ SetDeviceID(device_id);
+ SetAuthToken(auth_token);
+ em::DeviceManagementRequest request_wrapper;
+ request_wrapper.mutable_register_request()->CopyFrom(request);
+ SetPayload(request_wrapper);
+}
+
+// Handles device unregistration jobs.
+class DeviceManagementUnregisterJob : public DeviceManagementJob {
public:
- UnregisterResponseHandler(
- DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate)
- : delegate_(delegate) {}
+ DeviceManagementUnregisterJob(
+ DeviceManagementBackendProxy* proxy,
+ const std::string& device_management_token,
+ const em::DeviceUnregisterRequest& request,
+ DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate);
+ virtual ~DeviceManagementUnregisterJob() {}
private:
- // ResponseHandler overrides.
- virtual void OnError(DeviceManagementBackend::ErrorCode error) {
+ // DeviceManagementJob overrides.
+ virtual void ProcessError(DeviceManagementBackend::ErrorCode error) {
delegate_->OnError(error);
}
virtual void ProcessResponse(const em::DeviceManagementResponse& response) {
@@ -265,18 +431,36 @@ class UnregisterResponseHandler : public ResponseHandler {
}
DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceManagementUnregisterJob);
};
-// Handles device policy responses.
-class PolicyResponseHandler : public ResponseHandler {
+DeviceManagementUnregisterJob::DeviceManagementUnregisterJob(
+ DeviceManagementBackendProxy* proxy,
+ const std::string& device_management_token,
+ const em::DeviceUnregisterRequest& request,
+ DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate)
+ : DeviceManagementJob(proxy, "unregister"),
+ delegate_(delegate) {
+ SetDeviceManagementToken(device_management_token);
+ em::DeviceManagementRequest request_wrapper;
+ request_wrapper.mutable_unregister_request()->CopyFrom(request);
+ SetPayload(request_wrapper);
+}
+
+// Handles policy request jobs.
+class DeviceManagementPolicyJob : public DeviceManagementJob {
public:
- PolicyResponseHandler(
- DeviceManagementBackend::DevicePolicyResponseDelegate* delegate)
- : delegate_(delegate) {}
+ DeviceManagementPolicyJob(
+ DeviceManagementBackendProxy* proxy,
+ const std::string& device_management_token,
+ const em::DevicePolicyRequest& request,
+ DeviceManagementBackend::DevicePolicyResponseDelegate* delegate);
+ virtual ~DeviceManagementPolicyJob() {}
private:
- // ResponseHandler overrides.
- virtual void OnError(DeviceManagementBackend::ErrorCode error) {
+ // DeviceManagementJob overrides.
+ virtual void ProcessError(DeviceManagementBackend::ErrorCode error) {
delegate_->OnError(error);
}
virtual void ProcessResponse(const em::DeviceManagementResponse& response) {
@@ -284,72 +468,135 @@ class PolicyResponseHandler : public ResponseHandler {
}
DeviceManagementBackend::DevicePolicyResponseDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceManagementPolicyJob);
};
-DeviceManagementBackendImpl::DeviceManagementBackendImpl(
- const std::string& server_url)
- : server_url_(server_url),
- request_context_getter_(
- new DeviceManagementBackendRequestContextGetter()) {
+DeviceManagementPolicyJob::DeviceManagementPolicyJob(
+ DeviceManagementBackendProxy* proxy,
+ const std::string& device_management_token,
+ const em::DevicePolicyRequest& request,
+ DeviceManagementBackend::DevicePolicyResponseDelegate* delegate)
+ : DeviceManagementJob(proxy, "policy"),
+ delegate_(delegate) {
+ SetDeviceManagementToken(device_management_token);
+ em::DeviceManagementRequest request_wrapper;
+ request_wrapper.mutable_policy_request()->CopyFrom(request);
+ SetPayload(request_wrapper);
}
-DeviceManagementBackendImpl::~DeviceManagementBackendImpl() {
- // Cancel all pending requests.
- STLDeleteContainerPairPointers(response_handlers_.begin(),
- response_handlers_.end());
+DeviceManagementBackendProxy::DeviceManagementBackendProxy(
+ DeviceManagementBackendImpl* backend)
+ : backend_instance_(backend) {
+ proxies().insert(this);
+}
+
+DeviceManagementBackendProxy::~DeviceManagementBackendProxy() {
+ // Swap to a helper, so we don't interfere with the unregistration on delete.
+ JobSet to_be_deleted;
+ to_be_deleted.swap(pending_jobs_);
+ for (JobSet::iterator job(to_be_deleted.begin());
+ job != to_be_deleted.end();
+ ++job) {
+ if (backend_instance_)
+ backend_instance_->CancelJob(*job);
+ delete *job;
+ }
+
+ proxies().erase(this);
+}
+
+void DeviceManagementBackendProxy::JobDone(DeviceManagementJob* job) {
+ pending_jobs_.erase(job);
+}
+
+// static
+void DeviceManagementBackendProxy::SwitchBackend(
+ DeviceManagementBackendImpl* backend) {
+ for (ProxySet::iterator proxy(proxies().begin());
+ proxy != proxies().end();
+ ++proxy) {
+ (*proxy)->ResetBackend(backend);
+ }
+}
+
+void DeviceManagementBackendProxy::ResetBackend(
+ DeviceManagementBackendImpl* backend) {
+ if (backend == backend_instance_)
+ return;
+
+ // Switch our jobs over to the new backend.
+ for (JobSet::iterator job(pending_jobs_.begin());
+ job != pending_jobs_.end();
+ ++job) {
+ if (backend_instance_)
+ backend_instance_->CancelJob(*job);
+ if (backend)
+ backend->StartJob(*job);
+ }
+
+ backend_instance_ = backend;
+}
+
+void DeviceManagementBackendProxy::AddJob(DeviceManagementJob* job) {
+ pending_jobs_.insert(job);
+ if (backend_instance_)
+ backend_instance_->StartJob(job);
}
-void DeviceManagementBackendImpl::ProcessRegisterRequest(
+void DeviceManagementBackendProxy::ProcessRegisterRequest(
const std::string& auth_token,
const std::string& device_id,
const em::DeviceRegisterRequest& request,
DeviceRegisterResponseDelegate* delegate) {
- em::DeviceManagementRequest request_wrapper;
- request_wrapper.mutable_register_request()->CopyFrom(request);
-
- URLQueryParameters params;
- PutCommonQueryParameters(&params);
- params.Put(kServiceParamRequest, "register");
- params.Put(kServiceParamDeviceID, device_id);
-
- CreateFetcher(request_wrapper,
- new RegisterResponseHandler(delegate),
- params.Encode(),
- kServiceTokenAuthHeader + auth_token);
+ AddJob(new DeviceManagementRegisterJob(this, auth_token, device_id, request,
+ delegate));
}
-void DeviceManagementBackendImpl::ProcessUnregisterRequest(
+void DeviceManagementBackendProxy::ProcessUnregisterRequest(
const std::string& device_management_token,
const em::DeviceUnregisterRequest& request,
DeviceUnregisterResponseDelegate* delegate) {
- em::DeviceManagementRequest request_wrapper;
- request_wrapper.mutable_unregister_request()->CopyFrom(request);
-
- URLQueryParameters params;
- PutCommonQueryParameters(&params);
- params.Put(kServiceParamRequest, "unregister");
-
- CreateFetcher(request_wrapper,
- new UnregisterResponseHandler(delegate),
- params.Encode(),
- kDMTokenAuthHeader + device_management_token);
+ AddJob(new DeviceManagementUnregisterJob(this, device_management_token,
+ request, delegate));
}
-void DeviceManagementBackendImpl::ProcessPolicyRequest(
+void DeviceManagementBackendProxy::ProcessPolicyRequest(
const std::string& device_management_token,
const em::DevicePolicyRequest& request,
DevicePolicyResponseDelegate* delegate) {
- em::DeviceManagementRequest request_wrapper;
- request_wrapper.mutable_policy_request()->CopyFrom(request);
+ AddJob(new DeviceManagementPolicyJob(this, device_management_token, request,
+ delegate));
+}
- URLQueryParameters params;
- PutCommonQueryParameters(&params);
- params.Put(kServiceParamRequest, "policy");
+base::LazyInstance<DeviceManagementBackendProxy::ProxySet>
+DeviceManagementBackendProxy::proxies_(base::LINKER_INITIALIZED);
- CreateFetcher(request_wrapper,
- new PolicyResponseHandler(delegate),
- params.Encode(),
- kDMTokenAuthHeader + device_management_token);
+DeviceManagementBackendImpl::~DeviceManagementBackendImpl() {
+ DeviceManagementBackendProxy::SwitchBackend(NULL);
+ instance_ = NULL;
+
+ // All running jobs should have been canceled by now.
+ DCHECK(pending_jobs_.empty());
+}
+
+// static
+DeviceManagementBackend* DeviceManagementBackendImpl::Get() {
+ return new DeviceManagementBackendProxy(instance_);
+}
+
+// static
+DeviceManagementBackendImpl*
+DeviceManagementBackendImpl::Initialize(Profile* profile) {
+ DCHECK(!instance_);
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kDeviceManagementUrl)) {
+ return new DeviceManagementBackendImpl(
+ command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl),
+ profile->GetRequestContext());
+ }
+
+ return NULL;
}
// static
@@ -361,6 +608,44 @@ std::string DeviceManagementBackendImpl::GetAgentString() {
version_info.LastChange().c_str());
}
+DeviceManagementBackendImpl::DeviceManagementBackendImpl(
+ const std::string& server_url,
+ URLRequestContextGetter* request_context_getter)
+ : server_url_(server_url),
+ request_context_getter_(
+ new DeviceManagementBackendRequestContextGetter(
+ request_context_getter)) {
+ DCHECK(!instance_);
+ instance_ = this;
+
+ // Tell the proxies there's a new backend.
+ DeviceManagementBackendProxy::SwitchBackend(this);
+}
+
+void DeviceManagementBackendImpl::StartJob(DeviceManagementJob* job) {
+ URLFetcher* fetcher = URLFetcher::Create(0, job->GetURL(server_url_),
+ URLFetcher::POST, this);
+ fetcher->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES |
+ net::LOAD_DISABLE_CACHE);
+ fetcher->set_request_context(request_context_getter_.get());
+ job->ConfigureRequest(fetcher);
+ pending_jobs_[fetcher] = job;
+ fetcher->Start();
+}
+
+void DeviceManagementBackendImpl::CancelJob(DeviceManagementJob* job) {
+ for (JobFetcherMap::iterator entry(pending_jobs_.begin());
+ entry != pending_jobs_.end();
+ ++entry) {
+ if (entry->second == job) {
+ delete entry->first;
+ pending_jobs_.erase(entry);
+ break;
+ }
+ }
+}
+
void DeviceManagementBackendImpl::OnURLFetchComplete(
const URLFetcher* source,
const GURL& url,
@@ -368,48 +653,17 @@ void DeviceManagementBackendImpl::OnURLFetchComplete(
int response_code,
const ResponseCookies& cookies,
const std::string& data) {
- ResponseHandlerMap::iterator entry(response_handlers_.find(source));
- if (entry != response_handlers_.end()) {
- ResponseHandler* handler = entry->second;
- handler->HandleResponse(status, response_code, cookies, data);
- response_handlers_.erase(entry);
- delete handler;
+ JobFetcherMap::iterator entry(pending_jobs_.find(source));
+ if (entry != pending_jobs_.end()) {
+ DeviceManagementJob* job = entry->second;
+ job->HandleResponse(status, response_code, cookies, data);
+ pending_jobs_.erase(entry);
} else {
NOTREACHED() << "Callback from foreign URL fetcher";
}
delete source;
}
-void DeviceManagementBackendImpl::CreateFetcher(
- const em::DeviceManagementRequest& request,
- ResponseHandler* handler,
- const std::string& query_params,
- const std::string& extra_headers) {
- scoped_ptr<ResponseHandler> handler_ptr(handler);
-
- // Construct the payload.
- std::string payload;
- if (!request.SerializeToString(&payload)) {
- handler->OnError(DeviceManagementBackend::kErrorRequestInvalid);
- return;
- }
-
- // Instantiate the fetcher.
- GURL url(server_url_ + '?' + query_params);
- URLFetcher* fetcher = URLFetcher::Create(0, url, URLFetcher::POST, this);
- fetcher->set_request_context(request_context_getter_.get());
- fetcher->set_upload_data("application/octet-stream", payload);
- fetcher->set_extra_request_headers(extra_headers);
- response_handlers_[fetcher] = handler_ptr.release();
-
- // Start the request. The fetcher will call OnURLFetchComplete when done.
- fetcher->Start();
-}
-
-void DeviceManagementBackendImpl::PutCommonQueryParameters(
- URLQueryParameters* params) {
- params->Put(kServiceParamDeviceType, kServiceValueDeviceType);
- params->Put(kServiceParamAgent, GetAgentString());
-}
+DeviceManagementBackendImpl* DeviceManagementBackendImpl::instance_ = NULL;
} // namespace policy

Powered by Google App Engine
This is Rietveld 408576698