Chromium Code Reviews| 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..44b1804789b6a9ca1a222c4ca748bb0e6a0c9c95 |
| --- /dev/null |
| +++ b/chrome/browser/policy/device_management_service.cc |
| @@ -0,0 +1,185 @@ |
| +// 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 "chrome/browser/browser_thread.h" |
| +#include "net/base/cookie_monster.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/policy/device_management_backend_impl.h" |
| +#include "chrome/common/net/url_request_context_getter.h" |
| + |
| +namespace policy { |
| + |
| +namespace { |
| + |
| +// 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(); |
| +}; |
| + |
| +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. |
| + accept_language_ = "*"; |
| + accept_charset_ = "*"; |
| +} |
| + |
| +DeviceManagementBackendRequestContext |
| + ::~DeviceManagementBackendRequestContext() { |
| + delete http_transaction_factory_; |
| + delete http_auth_handler_factory_; |
| +} |
| + |
| +// 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 |
| + |
| +DeviceManagementService::~DeviceManagementService() { |
| + // All running jobs should have been canceled by now. If not, there are |
| + // backend objects still around, which is an error. |
| + DCHECK(pending_jobs_.empty()); |
| + DCHECK(queued_jobs_.empty()); |
| +} |
| + |
| +DeviceManagementBackend* DeviceManagementService::CreateBackend() { |
| + return new DeviceManagementBackendImpl(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() { |
|
Nico
2010/11/22 11:06:06
This moves all in-flight jobs back to the "queued"
Mattias Nissler (ping if slow)
2010/11/22 12:35:39
The backends should call RemoveJob() when they get
|
| + for (JobFetcherMap::iterator job(pending_jobs_.begin()); |
| + job != pending_jobs_.end(); |
| + ++job) { |
| + delete job->first; |
| + queued_jobs_.push_back(job->second); |
| + } |
| +} |
| + |
| +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"; |
|
Nico
2010/11/22 11:06:06
Doesn't this happen in normal usage if a few reque
Mattias Nissler (ping if slow)
2010/11/22 12:35:39
No, shutdown deletes the fetcher, thus cancelling
|
| + } |
| + delete source; |
| +} |
| + |
| +} // namespace policy |