| Index: chrome/browser/policy/device_management_service.cc
|
| diff --git a/chrome/browser/policy/device_management_service.cc b/chrome/browser/policy/device_management_service.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..632c68c657ec72f11331fdb5ee69228a85708bf9
|
| --- /dev/null
|
| +++ b/chrome/browser/policy/device_management_service.cc
|
| @@ -0,0 +1,619 @@
|
| +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/policy/device_management_service.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"
|
| +#include "net/proxy/proxy_service.h"
|
| +#include "net/url_request/url_request_context.h"
|
| +#include "net/url_request/url_request_status.h"
|
| +#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 {
|
| +
|
| +namespace {
|
| +
|
| +// Name constants for URL query parameters.
|
| +const char kServiceParamRequest[] = "request";
|
| +const char kServiceParamDeviceType[] = "devicetype";
|
| +const char kServiceParamDeviceID[] = "deviceid";
|
| +const char kServiceParamAgent[] = "agent";
|
| +
|
| +// String constants for the device type and agent we report to the service.
|
| +const char kServiceValueDeviceType[] = "Chrome";
|
| +const char kServiceValueAgent[] =
|
| + "%s enterprise management client version %s (%s)";
|
| +
|
| +const char kServiceTokenAuthHeader[] = "Authorization: GoogleLogin auth=";
|
| +const char kDMTokenAuthHeader[] = "Authorization: GoogleDMToken token=";
|
| +
|
| +// Helper class for URL query parameter encoding/decoding.
|
| +class URLQueryParameters {
|
| + 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. Wraps a baseline request context from which we reuse the
|
| +// networking components.
|
| +class DeviceManagementBackendRequestContext : public URLRequestContext {
|
| + public:
|
| + explicit DeviceManagementBackendRequestContext(
|
| + URLRequestContext* base_context);
|
| + virtual ~DeviceManagementBackendRequestContext();
|
| +
|
| + private:
|
| + virtual const std::string& GetUserAgent(const GURL& url) const;
|
| +
|
| + std::string user_agent_;
|
| +};
|
| +
|
| +DeviceManagementBackendRequestContext::DeviceManagementBackendRequestContext(
|
| + 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_ = DeviceManagementService::GetAgentString();
|
| + accept_language_ = "*";
|
| + accept_charset_ = "*";
|
| +}
|
| +
|
| +DeviceManagementBackendRequestContext
|
| + ::~DeviceManagementBackendRequestContext() {
|
| + delete http_transaction_factory_;
|
| + delete http_auth_handler_factory_;
|
| +}
|
| +
|
| +const std::string&
|
| +DeviceManagementBackendRequestContext::GetUserAgent(const GURL& url) const {
|
| + return user_agent_;
|
| +}
|
| +
|
| +// Request context holder.
|
| +class DeviceManagementBackendRequestContextGetter
|
| + : public URLRequestContextGetter {
|
| + public:
|
| + DeviceManagementBackendRequestContextGetter(
|
| + URLRequestContextGetter* base_context_getter)
|
| + : base_context_getter_(base_context_getter) {}
|
| +
|
| + // URLRequestContextGetter overrides.
|
| + virtual URLRequestContext* GetURLRequestContext();
|
| + virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const;
|
| +
|
| + private:
|
| + scoped_refptr<URLRequestContext> context_;
|
| + scoped_refptr<URLRequestContextGetter> base_context_getter_;
|
| +};
|
| +
|
| +
|
| +URLRequestContext*
|
| +DeviceManagementBackendRequestContextGetter::GetURLRequestContext() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + if (!context_) {
|
| + context_ = new DeviceManagementBackendRequestContext(
|
| + base_context_getter_->GetURLRequestContext());
|
| + }
|
| +
|
| + return context_.get();
|
| +}
|
| +
|
| +scoped_refptr<base::MessageLoopProxy>
|
| +DeviceManagementBackendRequestContextGetter::GetIOMessageLoopProxy() const {
|
| + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// A wrapper that implements the actual backend interface. This is separate from
|
| +// DeviceManagementService so the consumer can cancel all pending requests by
|
| +// destroying the backend object.
|
| +class DeviceManagementBackendProxy : public DeviceManagementBackend {
|
| + public:
|
| + explicit DeviceManagementBackendProxy(DeviceManagementService* service);
|
| + virtual ~DeviceManagementBackendProxy();
|
| +
|
| + // Called by the DeviceManagementJob dtor so we can clean up.
|
| + void JobDone(DeviceManagementJob* job);
|
| +
|
| + private:
|
| + typedef std::set<DeviceManagementJob*> JobSet;
|
| +
|
| + // Add a job to the pending job set and register it with the service (if
|
| + // available).
|
| + void AddJob(DeviceManagementJob* job);
|
| +
|
| + // DeviceManagementBackend overrides.
|
| + 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);
|
| +
|
| + // Keeps track of the jobs currently in flight.
|
| + JobSet pending_jobs_;
|
| +
|
| + DeviceManagementService* service_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DeviceManagementBackendProxy);
|
| +};
|
| +
|
| +// Represents a job run by the service. This contains the common code,
|
| +// subclasses provide custom code for actual register, unregister, and policy
|
| +// jobs.
|
| +class DeviceManagementJob {
|
| + public:
|
| + virtual ~DeviceManagementJob() {
|
| + proxy_->JobDone(this);
|
| + }
|
| +
|
| + // Handles the URL request response.
|
| + void HandleResponse(const URLRequestStatus& status,
|
| + int response_code,
|
| + const ResponseCookies& cookies,
|
| + const std::string& data);
|
| +
|
| + // 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,
|
| + DeviceManagementService::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 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 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) {
|
| + ProcessError(DeviceManagementBackend::kErrorRequestFailed);
|
| + return;
|
| + }
|
| +
|
| + if (response_code != 200) {
|
| + ProcessError(DeviceManagementBackend::kErrorHttpStatus);
|
| + return;
|
| + }
|
| +
|
| + em::DeviceManagementResponse response;
|
| + if (!response.ParseFromString(data)) {
|
| + ProcessError(DeviceManagementBackend::kErrorResponseDecoding);
|
| + return;
|
| + }
|
| +
|
| + // Check service error code.
|
| + switch (response.error()) {
|
| + case em::DeviceManagementResponse::SUCCESS:
|
| + break;
|
| + case em::DeviceManagementResponse::DEVICE_MANAGEMENT_NOT_SUPPORTED:
|
| + ProcessError(
|
| + DeviceManagementBackend::kErrorServiceManagementNotSupported);
|
| + return;
|
| + case em::DeviceManagementResponse::DEVICE_NOT_FOUND:
|
| + ProcessError(DeviceManagementBackend::kErrorServiceDeviceNotFound);
|
| + return;
|
| + case em::DeviceManagementResponse::DEVICE_MANAGEMENT_TOKEN_INVALID:
|
| + ProcessError(
|
| + DeviceManagementBackend::kErrorServiceManagementTokenInvalid);
|
| + return;
|
| + case em::DeviceManagementResponse::ACTIVATION_PENDING:
|
| + ProcessError(DeviceManagementBackend::kErrorServiceActivationPending);
|
| + return;
|
| + default:
|
| + // This should be caught by the protobuf decoder.
|
| + NOTREACHED();
|
| + ProcessError(DeviceManagementBackend::kErrorResponseDecoding);
|
| + return;
|
| + }
|
| +
|
| + ProcessResponse(response);
|
| +}
|
| +
|
| +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:
|
| + DeviceManagementRegisterJob(
|
| + DeviceManagementBackendProxy* proxy,
|
| + const std::string& auth_token,
|
| + const std::string& device_id,
|
| + const em::DeviceRegisterRequest& request,
|
| + DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate);
|
| + virtual ~DeviceManagementRegisterJob() {}
|
| +
|
| + private:
|
| + // DeviceManagementJob overrides.
|
| + virtual void ProcessError(DeviceManagementBackend::ErrorCode error) {
|
| + delegate_->OnError(error);
|
| + }
|
| + virtual void ProcessResponse(const em::DeviceManagementResponse& response) {
|
| + delegate_->HandleRegisterResponse(response.register_response());
|
| + }
|
| +
|
| + DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DeviceManagementRegisterJob);
|
| +};
|
| +
|
| +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:
|
| + DeviceManagementUnregisterJob(
|
| + DeviceManagementBackendProxy* proxy,
|
| + const std::string& device_management_token,
|
| + const em::DeviceUnregisterRequest& request,
|
| + DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate);
|
| + virtual ~DeviceManagementUnregisterJob() {}
|
| +
|
| + private:
|
| + // DeviceManagementJob overrides.
|
| + virtual void ProcessError(DeviceManagementBackend::ErrorCode error) {
|
| + delegate_->OnError(error);
|
| + }
|
| + virtual void ProcessResponse(const em::DeviceManagementResponse& response) {
|
| + delegate_->HandleUnregisterResponse(response.unregister_response());
|
| + }
|
| +
|
| + DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DeviceManagementUnregisterJob);
|
| +};
|
| +
|
| +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:
|
| + DeviceManagementPolicyJob(
|
| + DeviceManagementBackendProxy* proxy,
|
| + const std::string& device_management_token,
|
| + const em::DevicePolicyRequest& request,
|
| + DeviceManagementBackend::DevicePolicyResponseDelegate* delegate);
|
| + virtual ~DeviceManagementPolicyJob() {}
|
| +
|
| + private:
|
| + // DeviceManagementJob overrides.
|
| + virtual void ProcessError(DeviceManagementBackend::ErrorCode error) {
|
| + delegate_->OnError(error);
|
| + }
|
| + virtual void ProcessResponse(const em::DeviceManagementResponse& response) {
|
| + delegate_->HandlePolicyResponse(response.policy_response());
|
| + }
|
| +
|
| + DeviceManagementBackend::DevicePolicyResponseDelegate* delegate_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DeviceManagementPolicyJob);
|
| +};
|
| +
|
| +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);
|
| +}
|
| +
|
| +DeviceManagementBackendProxy::DeviceManagementBackendProxy(
|
| + DeviceManagementService* service)
|
| + : service_(service) {
|
| +}
|
| +
|
| +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) {
|
| + service_->RemoveJob(*job);
|
| + delete *job;
|
| + }
|
| +}
|
| +
|
| +void DeviceManagementBackendProxy::JobDone(DeviceManagementJob* job) {
|
| + pending_jobs_.erase(job);
|
| +}
|
| +
|
| +void DeviceManagementBackendProxy::AddJob(DeviceManagementJob* job) {
|
| + pending_jobs_.insert(job);
|
| + service_->AddJob(job);
|
| +}
|
| +
|
| +void DeviceManagementBackendProxy::ProcessRegisterRequest(
|
| + const std::string& auth_token,
|
| + const std::string& device_id,
|
| + const em::DeviceRegisterRequest& request,
|
| + DeviceRegisterResponseDelegate* delegate) {
|
| + AddJob(new DeviceManagementRegisterJob(this, auth_token, device_id, request,
|
| + delegate));
|
| +}
|
| +
|
| +void DeviceManagementBackendProxy::ProcessUnregisterRequest(
|
| + const std::string& device_management_token,
|
| + const em::DeviceUnregisterRequest& request,
|
| + DeviceUnregisterResponseDelegate* delegate) {
|
| + AddJob(new DeviceManagementUnregisterJob(this, device_management_token,
|
| + request, delegate));
|
| +}
|
| +
|
| +void DeviceManagementBackendProxy::ProcessPolicyRequest(
|
| + const std::string& device_management_token,
|
| + const em::DevicePolicyRequest& request,
|
| + DevicePolicyResponseDelegate* delegate) {
|
| + AddJob(new DeviceManagementPolicyJob(this, device_management_token, request,
|
| + delegate));
|
| +}
|
| +
|
| +DeviceManagementService::~DeviceManagementService() {
|
| + // All running jobs should have been canceled by now. If not, there are proxy
|
| + // objects still around, which is an error.
|
| + DCHECK(pending_jobs_.empty());
|
| + DCHECK(queued_jobs_.empty());
|
| +}
|
| +
|
| +DeviceManagementBackend* DeviceManagementService::CreateBackend() {
|
| + return new DeviceManagementBackendProxy(this);
|
| +}
|
| +
|
| +void DeviceManagementService::Initialize(
|
| + URLRequestContextGetter* request_context_getter) {
|
| + DCHECK(!request_context_getter_);
|
| + request_context_getter_ = request_context_getter;
|
| + while (!queued_jobs_.empty()) {
|
| + StartJob(queued_jobs_.front());
|
| + queued_jobs_.pop_front();
|
| + }
|
| +}
|
| +
|
| +void DeviceManagementService::Shutdown() {
|
| + for (JobFetcherMap::iterator job(pending_jobs_.begin());
|
| + job != pending_jobs_.end();
|
| + ++job) {
|
| + delete job->first;
|
| + queued_jobs_.push_back(job->second);
|
| + }
|
| +}
|
| +
|
| +// static
|
| +std::string DeviceManagementService::GetAgentString() {
|
| + chrome::VersionInfo version_info;
|
| + return base::StringPrintf(kServiceValueAgent,
|
| + version_info.Name().c_str(),
|
| + version_info.Version().c_str(),
|
| + version_info.LastChange().c_str());
|
| +}
|
| +
|
| +DeviceManagementService::DeviceManagementService(
|
| + const std::string& server_url)
|
| + : server_url_(server_url) {
|
| +}
|
| +
|
| +void DeviceManagementService::AddJob(DeviceManagementJob* job) {
|
| + if (request_context_getter_.get())
|
| + StartJob(job);
|
| + else
|
| + queued_jobs_.push_back(job);
|
| +}
|
| +
|
| +void DeviceManagementService::RemoveJob(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 DeviceManagementService::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 DeviceManagementService::OnURLFetchComplete(
|
| + const URLFetcher* source,
|
| + const GURL& url,
|
| + const URLRequestStatus& status,
|
| + int response_code,
|
| + const ResponseCookies& cookies,
|
| + const std::string& data) {
|
| + 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;
|
| +}
|
| +
|
| +} // namespace policy
|
|
|