OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/policy/device_management_service.h" | |
6 | |
7 #include <utility> | |
8 #include <set> | |
9 #include <vector> | |
10 | |
11 #include "base/command_line.h" | |
12 #include "base/lazy_instance.h" | |
13 #include "base/stl_util-inl.h" | |
14 #include "base/stringprintf.h" | |
15 #include "chrome/browser/browser_thread.h" | |
16 #include "chrome/common/chrome_switches.h" | |
17 #include "chrome/common/net/url_request_context_getter.h" | |
18 #include "net/base/cookie_monster.h" | |
19 #include "net/base/escape.h" | |
20 #include "net/base/host_resolver.h" | |
21 #include "net/base/load_flags.h" | |
22 #include "net/base/ssl_config_service_defaults.h" | |
23 #include "net/http/http_auth_handler_factory.h" | |
24 #include "net/http/http_network_layer.h" | |
25 #include "net/proxy/proxy_service.h" | |
26 #include "net/url_request/url_request_context.h" | |
27 #include "net/url_request/url_request_status.h" | |
28 #include "chrome/browser/browser_process.h" | |
29 #include "chrome/browser/io_thread.h" | |
30 #include "chrome/browser/net/chrome_net_log.h" | |
31 #include "chrome/browser/profile.h" | |
32 #include "chrome/common/chrome_switches.h" | |
33 #include "chrome/common/chrome_version_info.h" | |
34 | |
35 namespace policy { | |
36 | |
37 namespace { | |
38 | |
39 // Name constants for URL query parameters. | |
40 const char kServiceParamRequest[] = "request"; | |
41 const char kServiceParamDeviceType[] = "devicetype"; | |
42 const char kServiceParamDeviceID[] = "deviceid"; | |
markusheintz_
2010/11/18 16:12:49
s/deviceid/device/
Mattias Nissler (ping if slow)
2010/11/19 16:03:56
Na, the parameter is really called deviceid.
markusheintz_
2010/11/19 17:13:13
Well the doc says something different, but I trust
| |
43 const char kServiceParamAgent[] = "agent"; | |
markusheintz_
2010/11/18 16:12:49
Please add:
const char kServiceParamAppType[] = "
Mattias Nissler (ping if slow)
2010/11/19 16:03:56
Done.
| |
44 | |
45 // String constants for the device type and agent we report to the service. | |
46 const char kServiceValueDeviceType[] = "Chrome"; | |
markusheintz_
2010/11/18 16:12:49
Pls add:
const char kServiceValueAppType[] = "Chr
Mattias Nissler (ping if slow)
2010/11/19 16:03:56
Done.
| |
47 const char kServiceValueAgent[] = | |
48 "%s enterprise management client version %s (%s)"; | |
49 | |
50 const char kServiceTokenAuthHeader[] = "Authorization: GoogleLogin auth="; | |
51 const char kDMTokenAuthHeader[] = "Authorization: GoogleDMToken token="; | |
52 | |
53 // Helper class for URL query parameter encoding/decoding. | |
54 class URLQueryParameters { | |
55 public: | |
56 URLQueryParameters() {} | |
57 | |
58 // Add a query parameter. | |
59 void Put(const std::string& name, const std::string& value); | |
60 | |
61 // Produce the query string, taking care of properly encoding and assembling | |
62 // the names and values. | |
63 std::string Encode(); | |
64 | |
65 private: | |
66 typedef std::vector<std::pair<std::string, std::string> > ParameterMap; | |
67 ParameterMap params_; | |
68 | |
69 DISALLOW_COPY_AND_ASSIGN(URLQueryParameters); | |
70 }; | |
71 | |
72 void URLQueryParameters::Put(const std::string& name, | |
73 const std::string& value) { | |
74 params_.push_back(std::make_pair(name, value)); | |
75 } | |
76 | |
77 std::string URLQueryParameters::Encode() { | |
78 std::string result; | |
79 for (ParameterMap::const_iterator entry(params_.begin()); | |
80 entry != params_.end(); | |
81 ++entry) { | |
82 if (entry != params_.begin()) | |
83 result += '&'; | |
84 result += EscapeUrlEncodedData(entry->first); | |
85 result += '='; | |
86 result += EscapeUrlEncodedData(entry->second); | |
87 } | |
88 return result; | |
89 } | |
90 | |
91 // Custom request context implementation that allows to override the user agent, | |
92 // amongst others. Wraps a baseline request context from which we reuse the | |
93 // networking components. | |
94 class DeviceManagementBackendRequestContext : public URLRequestContext { | |
95 public: | |
96 explicit DeviceManagementBackendRequestContext( | |
97 URLRequestContext* base_context); | |
98 virtual ~DeviceManagementBackendRequestContext(); | |
99 | |
100 private: | |
101 virtual const std::string& GetUserAgent(const GURL& url) const; | |
102 | |
103 std::string user_agent_; | |
104 }; | |
105 | |
106 DeviceManagementBackendRequestContext::DeviceManagementBackendRequestContext( | |
107 URLRequestContext* base_context) { | |
108 // Share resolver, proxy service and ssl bits with the baseline context. This | |
109 // is important so we don't make redundant requests (e.g. when resolving proxy | |
110 // auto configuration). | |
111 net_log_ = base_context->net_log(); | |
112 host_resolver_ = base_context->host_resolver(); | |
113 proxy_service_ = base_context->proxy_service(); | |
114 ssl_config_service_ = base_context->ssl_config_service(); | |
115 | |
116 // Share the http session. | |
117 http_transaction_factory_ = net::HttpNetworkLayer::CreateFactory( | |
118 base_context->http_transaction_factory()->GetSession()); | |
119 | |
120 // No cookies, please. | |
121 cookie_store_ = new net::CookieMonster(NULL, NULL); | |
122 | |
123 // Initialize these to sane values for our purposes. | |
124 user_agent_ = DeviceManagementService::GetAgentString(); | |
125 accept_language_ = "*"; | |
126 accept_charset_ = "*"; | |
127 } | |
128 | |
129 DeviceManagementBackendRequestContext | |
130 ::~DeviceManagementBackendRequestContext() { | |
131 delete http_transaction_factory_; | |
132 delete http_auth_handler_factory_; | |
133 } | |
134 | |
135 const std::string& | |
136 DeviceManagementBackendRequestContext::GetUserAgent(const GURL& url) const { | |
137 return user_agent_; | |
138 } | |
139 | |
140 // Request context holder. | |
141 class DeviceManagementBackendRequestContextGetter | |
142 : public URLRequestContextGetter { | |
143 public: | |
144 DeviceManagementBackendRequestContextGetter( | |
145 URLRequestContextGetter* base_context_getter) | |
146 : base_context_getter_(base_context_getter) {} | |
147 | |
148 // URLRequestContextGetter overrides. | |
149 virtual URLRequestContext* GetURLRequestContext(); | |
150 virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const; | |
151 | |
152 private: | |
153 scoped_refptr<URLRequestContext> context_; | |
154 scoped_refptr<URLRequestContextGetter> base_context_getter_; | |
155 }; | |
156 | |
157 | |
158 URLRequestContext* | |
159 DeviceManagementBackendRequestContextGetter::GetURLRequestContext() { | |
160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
161 if (!context_) { | |
162 context_ = new DeviceManagementBackendRequestContext( | |
163 base_context_getter_->GetURLRequestContext()); | |
164 } | |
165 | |
166 return context_.get(); | |
167 } | |
168 | |
169 scoped_refptr<base::MessageLoopProxy> | |
170 DeviceManagementBackendRequestContextGetter::GetIOMessageLoopProxy() const { | |
171 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); | |
172 } | |
173 | |
174 } // namespace | |
175 | |
176 // A wrapper that implements the actual backend interface. This is separate from | |
markusheintz_
2010/11/18 16:12:49
This class could live in its own .h .cc file.
Wdy
Mattias Nissler (ping if slow)
2010/11/19 16:03:56
Done. Also renamed to DeviceManagementBackendImpl.
| |
177 // DeviceManagementService so the consumer can cancel all pending requests by | |
178 // destroying the backend object. | |
179 class DeviceManagementBackendProxy : public DeviceManagementBackend { | |
180 public: | |
181 explicit DeviceManagementBackendProxy(DeviceManagementService* service); | |
182 virtual ~DeviceManagementBackendProxy(); | |
183 | |
184 // Called by the DeviceManagementJob dtor so we can clean up. | |
185 void JobDone(DeviceManagementJob* job); | |
186 | |
187 private: | |
188 typedef std::set<DeviceManagementJob*> JobSet; | |
189 | |
190 // Add a job to the pending job set and register it with the service (if | |
191 // available). | |
192 void AddJob(DeviceManagementJob* job); | |
193 | |
194 // DeviceManagementBackend overrides. | |
195 virtual void ProcessRegisterRequest( | |
196 const std::string& auth_token, | |
197 const std::string& device_id, | |
198 const em::DeviceRegisterRequest& request, | |
199 DeviceRegisterResponseDelegate* response_delegate); | |
200 virtual void ProcessUnregisterRequest( | |
201 const std::string& device_management_token, | |
202 const em::DeviceUnregisterRequest& request, | |
203 DeviceUnregisterResponseDelegate* response_delegate); | |
204 virtual void ProcessPolicyRequest( | |
205 const std::string& device_management_token, | |
206 const em::DevicePolicyRequest& request, | |
207 DevicePolicyResponseDelegate* response_delegate); | |
208 | |
209 // Keeps track of the jobs currently in flight. | |
210 JobSet pending_jobs_; | |
211 | |
212 DeviceManagementService* service_; | |
213 | |
214 DISALLOW_COPY_AND_ASSIGN(DeviceManagementBackendProxy); | |
215 }; | |
216 | |
217 // Represents a job run by the service. This contains the common code, | |
markusheintz_
2010/11/18 16:12:49
I somehow think the DeviceManagementJob classes sh
Mattias Nissler (ping if slow)
2010/11/19 16:03:56
These are really implementation details for the Ba
| |
218 // subclasses provide custom code for actual register, unregister, and policy | |
219 // jobs. | |
220 class DeviceManagementJob { | |
221 public: | |
222 virtual ~DeviceManagementJob() { | |
223 proxy_->JobDone(this); | |
224 } | |
225 | |
226 // Handles the URL request response. | |
227 void HandleResponse(const URLRequestStatus& status, | |
228 int response_code, | |
229 const ResponseCookies& cookies, | |
230 const std::string& data); | |
231 | |
232 // Gets the URL to contact. | |
233 GURL GetURL(const std::string& server_url); | |
234 | |
235 // Configures the fetcher, setting up payload and headers. | |
236 void ConfigureRequest(URLFetcher* fetcher); | |
237 | |
238 protected: | |
239 // Constructs a device management job running for the given proxy. | |
240 DeviceManagementJob(DeviceManagementBackendProxy* proxy, | |
241 const std::string& request_type) | |
242 : proxy_(proxy) { | |
243 query_params_.Put(kServiceParamRequest, request_type); | |
244 query_params_.Put(kServiceParamDeviceType, kServiceValueDeviceType); | |
markusheintz_
2010/11/18 16:12:49
Pls add:
query_params_.Put(kServiceParamAppType,
Mattias Nissler (ping if slow)
2010/11/19 16:03:56
Done.
| |
245 query_params_.Put(kServiceParamAgent, | |
246 DeviceManagementService::GetAgentString()); | |
247 } | |
248 | |
249 void SetQueryParam(const std::string& name, const std::string& value) { | |
250 query_params_.Put(name, value); | |
251 } | |
252 | |
253 void SetAuthToken(const std::string& auth_token) { | |
254 auth_token_ = auth_token; | |
255 } | |
256 | |
257 void SetDeviceManagementToken(const std::string& device_management_token) { | |
258 device_management_token_ = device_management_token; | |
259 } | |
260 | |
261 void SetDeviceID(const std::string& device_id) { | |
262 query_params_.Put(kServiceParamDeviceID, device_id); | |
263 } | |
264 | |
265 void SetPayload(const em::DeviceManagementRequest& request) { | |
266 if (!request.SerializeToString(&payload_)) { | |
267 NOTREACHED(); | |
268 LOG(ERROR) << "Failed to serialize request."; | |
269 } | |
270 } | |
271 | |
272 private: | |
273 // Implemented by subclasses to handle decoded responses and errors. | |
274 virtual void ProcessResponse( | |
275 const em::DeviceManagementResponse& response) = 0; | |
276 virtual void ProcessError(DeviceManagementBackend::ErrorCode error) = 0; | |
277 | |
278 // The proxy this job is handling a request for. | |
279 DeviceManagementBackendProxy* proxy_; | |
280 | |
281 // Query parameters. | |
282 URLQueryParameters query_params_; | |
283 | |
284 // Auth token (if applicaple). | |
285 std::string auth_token_; | |
286 | |
287 // Device management token (if applicable). | |
288 std::string device_management_token_; | |
289 | |
290 // The payload. | |
291 std::string payload_; | |
292 | |
293 DISALLOW_COPY_AND_ASSIGN(DeviceManagementJob); | |
294 }; | |
295 | |
296 void DeviceManagementJob::HandleResponse(const URLRequestStatus& status, | |
297 int response_code, | |
298 const ResponseCookies& cookies, | |
299 const std::string& data) { | |
300 // Delete ourselves when this is done. | |
301 scoped_ptr<DeviceManagementJob> scoped_killer(this); | |
302 | |
303 if (status.status() != URLRequestStatus::SUCCESS) { | |
304 ProcessError(DeviceManagementBackend::kErrorRequestFailed); | |
305 return; | |
306 } | |
307 | |
308 if (response_code != 200) { | |
309 ProcessError(DeviceManagementBackend::kErrorHttpStatus); | |
310 return; | |
311 } | |
312 | |
313 em::DeviceManagementResponse response; | |
314 if (!response.ParseFromString(data)) { | |
315 ProcessError(DeviceManagementBackend::kErrorResponseDecoding); | |
316 return; | |
317 } | |
318 | |
319 // Check service error code. | |
320 switch (response.error()) { | |
321 case em::DeviceManagementResponse::SUCCESS: | |
322 break; | |
323 case em::DeviceManagementResponse::DEVICE_MANAGEMENT_NOT_SUPPORTED: | |
324 ProcessError( | |
325 DeviceManagementBackend::kErrorServiceManagementNotSupported); | |
326 return; | |
327 case em::DeviceManagementResponse::DEVICE_NOT_FOUND: | |
328 ProcessError(DeviceManagementBackend::kErrorServiceDeviceNotFound); | |
329 return; | |
330 case em::DeviceManagementResponse::DEVICE_MANAGEMENT_TOKEN_INVALID: | |
331 ProcessError( | |
332 DeviceManagementBackend::kErrorServiceManagementTokenInvalid); | |
333 return; | |
334 case em::DeviceManagementResponse::ACTIVATION_PENDING: | |
335 ProcessError(DeviceManagementBackend::kErrorServiceActivationPending); | |
336 return; | |
337 default: | |
338 // This should be caught by the protobuf decoder. | |
339 NOTREACHED(); | |
340 ProcessError(DeviceManagementBackend::kErrorResponseDecoding); | |
341 return; | |
342 } | |
343 | |
344 ProcessResponse(response); | |
345 } | |
346 | |
347 GURL DeviceManagementJob::GetURL(const std::string& server_url) { | |
348 return GURL(server_url + '?' + query_params_.Encode()); | |
349 } | |
350 | |
351 void DeviceManagementJob::ConfigureRequest(URLFetcher* fetcher) { | |
352 fetcher->set_upload_data("application/octet-stream", payload_); | |
353 std::string extra_headers; | |
354 if (!auth_token_.empty()) | |
355 extra_headers += kServiceTokenAuthHeader + auth_token_ + "\n"; | |
356 if (!device_management_token_.empty()) | |
357 extra_headers += kDMTokenAuthHeader + device_management_token_ + "\n"; | |
358 fetcher->set_extra_request_headers(extra_headers); | |
359 } | |
360 | |
361 // Handles device registration jobs. | |
362 class DeviceManagementRegisterJob : public DeviceManagementJob { | |
363 public: | |
364 DeviceManagementRegisterJob( | |
365 DeviceManagementBackendProxy* proxy, | |
366 const std::string& auth_token, | |
367 const std::string& device_id, | |
368 const em::DeviceRegisterRequest& request, | |
369 DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate); | |
370 virtual ~DeviceManagementRegisterJob() {} | |
371 | |
372 private: | |
373 // DeviceManagementJob overrides. | |
374 virtual void ProcessError(DeviceManagementBackend::ErrorCode error) { | |
markusheintz_
2010/11/18 16:12:49
Why naming ProcessError if the delegate's method i
Mattias Nissler (ping if slow)
2010/11/19 16:03:56
Done.
| |
375 delegate_->OnError(error); | |
376 } | |
377 virtual void ProcessResponse(const em::DeviceManagementResponse& response) { | |
378 delegate_->HandleRegisterResponse(response.register_response()); | |
379 } | |
380 | |
381 DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate_; | |
382 | |
383 DISALLOW_COPY_AND_ASSIGN(DeviceManagementRegisterJob); | |
384 }; | |
385 | |
386 DeviceManagementRegisterJob::DeviceManagementRegisterJob( | |
387 DeviceManagementBackendProxy* proxy, | |
388 const std::string& auth_token, | |
389 const std::string& device_id, | |
390 const em::DeviceRegisterRequest& request, | |
391 DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate) | |
392 : DeviceManagementJob(proxy, "register"), | |
393 delegate_(delegate) { | |
394 SetDeviceID(device_id); | |
395 SetAuthToken(auth_token); | |
396 em::DeviceManagementRequest request_wrapper; | |
397 request_wrapper.mutable_register_request()->CopyFrom(request); | |
398 SetPayload(request_wrapper); | |
399 } | |
400 | |
401 // Handles device unregistration jobs. | |
402 class DeviceManagementUnregisterJob : public DeviceManagementJob { | |
403 public: | |
404 DeviceManagementUnregisterJob( | |
405 DeviceManagementBackendProxy* proxy, | |
406 const std::string& device_management_token, | |
407 const em::DeviceUnregisterRequest& request, | |
408 DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate); | |
409 virtual ~DeviceManagementUnregisterJob() {} | |
410 | |
411 private: | |
412 // DeviceManagementJob overrides. | |
413 virtual void ProcessError(DeviceManagementBackend::ErrorCode error) { | |
414 delegate_->OnError(error); | |
415 } | |
416 virtual void ProcessResponse(const em::DeviceManagementResponse& response) { | |
417 delegate_->HandleUnregisterResponse(response.unregister_response()); | |
418 } | |
419 | |
420 DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate_; | |
421 | |
422 DISALLOW_COPY_AND_ASSIGN(DeviceManagementUnregisterJob); | |
423 }; | |
424 | |
425 DeviceManagementUnregisterJob::DeviceManagementUnregisterJob( | |
426 DeviceManagementBackendProxy* proxy, | |
427 const std::string& device_management_token, | |
428 const em::DeviceUnregisterRequest& request, | |
429 DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate) | |
430 : DeviceManagementJob(proxy, "unregister"), | |
431 delegate_(delegate) { | |
432 SetDeviceManagementToken(device_management_token); | |
433 em::DeviceManagementRequest request_wrapper; | |
434 request_wrapper.mutable_unregister_request()->CopyFrom(request); | |
435 SetPayload(request_wrapper); | |
436 } | |
437 | |
438 // Handles policy request jobs. | |
439 class DeviceManagementPolicyJob : public DeviceManagementJob { | |
440 public: | |
441 DeviceManagementPolicyJob( | |
442 DeviceManagementBackendProxy* proxy, | |
443 const std::string& device_management_token, | |
444 const em::DevicePolicyRequest& request, | |
445 DeviceManagementBackend::DevicePolicyResponseDelegate* delegate); | |
446 virtual ~DeviceManagementPolicyJob() {} | |
447 | |
448 private: | |
449 // DeviceManagementJob overrides. | |
450 virtual void ProcessError(DeviceManagementBackend::ErrorCode error) { | |
451 delegate_->OnError(error); | |
452 } | |
453 virtual void ProcessResponse(const em::DeviceManagementResponse& response) { | |
454 delegate_->HandlePolicyResponse(response.policy_response()); | |
455 } | |
456 | |
457 DeviceManagementBackend::DevicePolicyResponseDelegate* delegate_; | |
458 | |
459 DISALLOW_COPY_AND_ASSIGN(DeviceManagementPolicyJob); | |
460 }; | |
461 | |
462 DeviceManagementPolicyJob::DeviceManagementPolicyJob( | |
463 DeviceManagementBackendProxy* proxy, | |
464 const std::string& device_management_token, | |
465 const em::DevicePolicyRequest& request, | |
466 DeviceManagementBackend::DevicePolicyResponseDelegate* delegate) | |
467 : DeviceManagementJob(proxy, "policy"), | |
468 delegate_(delegate) { | |
469 SetDeviceManagementToken(device_management_token); | |
470 em::DeviceManagementRequest request_wrapper; | |
471 request_wrapper.mutable_policy_request()->CopyFrom(request); | |
472 SetPayload(request_wrapper); | |
473 } | |
474 | |
475 DeviceManagementBackendProxy::DeviceManagementBackendProxy( | |
476 DeviceManagementService* service) | |
477 : service_(service) { | |
478 } | |
479 | |
480 DeviceManagementBackendProxy::~DeviceManagementBackendProxy() { | |
481 // Swap to a helper, so we don't interfere with the unregistration on delete. | |
482 JobSet to_be_deleted; | |
483 to_be_deleted.swap(pending_jobs_); | |
484 for (JobSet::iterator job(to_be_deleted.begin()); | |
485 job != to_be_deleted.end(); | |
486 ++job) { | |
487 service_->RemoveJob(*job); | |
488 delete *job; | |
489 } | |
490 } | |
491 | |
492 void DeviceManagementBackendProxy::JobDone(DeviceManagementJob* job) { | |
493 pending_jobs_.erase(job); | |
494 } | |
495 | |
496 void DeviceManagementBackendProxy::AddJob(DeviceManagementJob* job) { | |
497 pending_jobs_.insert(job); | |
498 service_->AddJob(job); | |
499 } | |
500 | |
501 void DeviceManagementBackendProxy::ProcessRegisterRequest( | |
502 const std::string& auth_token, | |
503 const std::string& device_id, | |
504 const em::DeviceRegisterRequest& request, | |
505 DeviceRegisterResponseDelegate* delegate) { | |
506 AddJob(new DeviceManagementRegisterJob(this, auth_token, device_id, request, | |
507 delegate)); | |
508 } | |
509 | |
510 void DeviceManagementBackendProxy::ProcessUnregisterRequest( | |
511 const std::string& device_management_token, | |
512 const em::DeviceUnregisterRequest& request, | |
513 DeviceUnregisterResponseDelegate* delegate) { | |
514 AddJob(new DeviceManagementUnregisterJob(this, device_management_token, | |
515 request, delegate)); | |
516 } | |
517 | |
518 void DeviceManagementBackendProxy::ProcessPolicyRequest( | |
519 const std::string& device_management_token, | |
520 const em::DevicePolicyRequest& request, | |
521 DevicePolicyResponseDelegate* delegate) { | |
522 AddJob(new DeviceManagementPolicyJob(this, device_management_token, request, | |
523 delegate)); | |
524 } | |
525 | |
526 DeviceManagementService::~DeviceManagementService() { | |
527 // All running jobs should have been canceled by now. If not, there are proxy | |
528 // objects still around, which is an error. | |
529 DCHECK(pending_jobs_.empty()); | |
530 DCHECK(queued_jobs_.empty()); | |
531 } | |
532 | |
533 DeviceManagementBackend* DeviceManagementService::CreateBackend() { | |
534 return new DeviceManagementBackendProxy(this); | |
535 } | |
536 | |
537 void DeviceManagementService::Initialize( | |
538 URLRequestContextGetter* request_context_getter) { | |
539 DCHECK(!request_context_getter_); | |
540 request_context_getter_ = request_context_getter; | |
541 while (!queued_jobs_.empty()) { | |
542 StartJob(queued_jobs_.front()); | |
543 queued_jobs_.pop_front(); | |
544 } | |
545 } | |
546 | |
547 void DeviceManagementService::Shutdown() { | |
548 for (JobFetcherMap::iterator job(pending_jobs_.begin()); | |
549 job != pending_jobs_.end(); | |
550 ++job) { | |
551 delete job->first; | |
552 queued_jobs_.push_back(job->second); | |
553 } | |
554 } | |
555 | |
556 // static | |
557 std::string DeviceManagementService::GetAgentString() { | |
558 chrome::VersionInfo version_info; | |
559 return base::StringPrintf(kServiceValueAgent, | |
560 version_info.Name().c_str(), | |
561 version_info.Version().c_str(), | |
562 version_info.LastChange().c_str()); | |
563 } | |
564 | |
565 DeviceManagementService::DeviceManagementService( | |
566 const std::string& server_url) | |
567 : server_url_(server_url) { | |
568 } | |
569 | |
570 void DeviceManagementService::AddJob(DeviceManagementJob* job) { | |
571 if (request_context_getter_.get()) | |
572 StartJob(job); | |
573 else | |
574 queued_jobs_.push_back(job); | |
575 } | |
576 | |
577 void DeviceManagementService::RemoveJob(DeviceManagementJob* job) { | |
578 for (JobFetcherMap::iterator entry(pending_jobs_.begin()); | |
579 entry != pending_jobs_.end(); | |
580 ++entry) { | |
581 if (entry->second == job) { | |
582 delete entry->first; | |
583 pending_jobs_.erase(entry); | |
584 break; | |
585 } | |
586 } | |
587 } | |
588 | |
589 void DeviceManagementService::StartJob(DeviceManagementJob* job) { | |
590 URLFetcher* fetcher = URLFetcher::Create(0, job->GetURL(server_url_), | |
591 URLFetcher::POST, this); | |
592 fetcher->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES | | |
593 net::LOAD_DO_NOT_SAVE_COOKIES | | |
594 net::LOAD_DISABLE_CACHE); | |
595 fetcher->set_request_context(request_context_getter_.get()); | |
596 job->ConfigureRequest(fetcher); | |
597 pending_jobs_[fetcher] = job; | |
598 fetcher->Start(); | |
599 } | |
600 | |
601 void DeviceManagementService::OnURLFetchComplete( | |
602 const URLFetcher* source, | |
603 const GURL& url, | |
604 const URLRequestStatus& status, | |
605 int response_code, | |
606 const ResponseCookies& cookies, | |
607 const std::string& data) { | |
608 JobFetcherMap::iterator entry(pending_jobs_.find(source)); | |
609 if (entry != pending_jobs_.end()) { | |
610 DeviceManagementJob* job = entry->second; | |
611 job->HandleResponse(status, response_code, cookies, data); | |
612 pending_jobs_.erase(entry); | |
613 } else { | |
614 NOTREACHED() << "Callback from foreign URL fetcher"; | |
615 } | |
616 delete source; | |
617 } | |
618 | |
619 } // namespace policy | |
OLD | NEW |