1// Copyright (c) 2012 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#ifndef CHROME_BROWSER_POLICY_CLOUD_DEVICE_MANAGEMENT_SERVICE_H_
6#define CHROME_BROWSER_POLICY_CLOUD_DEVICE_MANAGEMENT_SERVICE_H_
7
8#include <deque>
9#include <map>
10#include <string>
11#include <vector>
12
13#include "base/basictypes.h"
14#include "base/callback.h"
15#include "base/compiler_specific.h"
16#include "base/memory/ref_counted.h"
17#include "base/memory/weak_ptr.h"
18#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
19#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
20#include "net/url_request/url_fetcher_delegate.h"
21
22namespace net {
23class URLRequestContextGetter;
24}
25
26namespace policy {
27
28class DeviceManagementRequestJobImpl;
29class DeviceManagementService;
30
31// DeviceManagementRequestJob describes a request to send to the device
32// management service. Jobs are created by DeviceManagementService. They can be
33// canceled by deleting the object.
34class DeviceManagementRequestJob {
35 public:
36  // Describes the job type.
37  enum JobType {
38    TYPE_AUTO_ENROLLMENT,
39    TYPE_REGISTRATION,
40    TYPE_API_AUTH_CODE_FETCH,
41    TYPE_POLICY_FETCH,
42    TYPE_UNREGISTRATION,
43    TYPE_UPLOAD_CERTIFICATE,
44  };
45
46  typedef base::Callback<
47      void(DeviceManagementStatus, int,
48           const enterprise_management::DeviceManagementResponse&)> Callback;
49
50  typedef base::Callback<void(DeviceManagementRequestJob*)> RetryCallback;
51
52  virtual ~DeviceManagementRequestJob();
53
54  // Functions for configuring the job. These should only be called before
55  // Start()ing the job, but never afterwards.
56  void SetGaiaToken(const std::string& gaia_token);
57  void SetOAuthToken(const std::string& oauth_token);
58  void SetUserAffiliation(UserAffiliation user_affiliation);
59  void SetDMToken(const std::string& dm_token);
60  void SetClientID(const std::string& client_id);
61  enterprise_management::DeviceManagementRequest* GetRequest();
62
63  // A job may automatically retry if it fails due to a temporary condition, or
64  // due to proxy misconfigurations. If a |retry_callback| is set then it will
65  // be invoked with the DeviceManagementRequestJob as an argument when that
66  // happens, so that the job's owner can customize the retry request before
67  // it's sent.
68  void SetRetryCallback(const RetryCallback& retry_callback);
69
70  // Starts the job. |callback| will be invoked on completion.
71  void Start(const Callback& callback);
72
73 protected:
74  typedef std::vector<std::pair<std::string, std::string> > ParameterMap;
75
76  explicit DeviceManagementRequestJob(JobType type);
77
78  // Appends a parameter to |query_params|.
79  void AddParameter(const std::string& name, const std::string& value);
80
81  // Fires the job, to be filled in by implementations.
82  virtual void Run() = 0;
83
84  ParameterMap query_params_;
85  std::string gaia_token_;
86  std::string dm_token_;
87  enterprise_management::DeviceManagementRequest request_;
88  RetryCallback retry_callback_;
89
90  Callback callback_;
91
92 private:
93  DISALLOW_COPY_AND_ASSIGN(DeviceManagementRequestJob);
94};
95
96// The device management service is responsible for everything related to
97// communication with the device management server. It creates the backends
98// objects that the device management policy provider and friends use to issue
99// requests.
100class DeviceManagementService : public net::URLFetcherDelegate {
101 public:
102  explicit DeviceManagementService(const std::string& server_url);
103  virtual ~DeviceManagementService();
104
105  // The ID of URLFetchers created by the DeviceManagementService. This can be
106  // used by tests that use a TestURLFetcherFactory to get the pending fetchers
107  // created by the DeviceManagementService.
108  static const int kURLFetcherID;
109
110  // Creates a new device management request job. Ownership is transferred to
111  // the caller.
112  virtual DeviceManagementRequestJob* CreateJob(
113      DeviceManagementRequestJob::JobType type);
114
115  // Schedules a task to run |Initialize| after |delay_milliseconds| had passed.
116  void ScheduleInitialization(int64 delay_milliseconds);
117
118  // Makes the service stop all requests and drop the reference to the request
119  // context.
120  void Shutdown();
121
122 private:
123  typedef std::map<const net::URLFetcher*,
124                   DeviceManagementRequestJobImpl*> JobFetcherMap;
125  typedef std::deque<DeviceManagementRequestJobImpl*> JobQueue;
126
127  friend class DeviceManagementRequestJobImpl;
128
129  // net::URLFetcherDelegate override.
130  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
131
132  // Does the actual initialization using the request context specified for
133  // |PrepareInitialization|. This will also fire any pending network requests.
134  void Initialize();
135
136  // Starts a job.
137  void StartJob(DeviceManagementRequestJobImpl* job);
138
139  // Adds a job. Caller must make sure the job pointer stays valid until the job
140  // completes or gets canceled via RemoveJob().
141  void AddJob(DeviceManagementRequestJobImpl* job);
142
143  // Removes a job. The job will be removed and won't receive a completion
144  // callback.
145  void RemoveJob(DeviceManagementRequestJobImpl* job);
146
147  // Server at which to contact the service.
148  const std::string server_url_;
149
150  // The request context we use.
151  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
152
153  // The jobs we currently have in flight.
154  JobFetcherMap pending_jobs_;
155
156  // Jobs that are registered, but not started yet.
157  JobQueue queued_jobs_;
158
159  // If this service is initialized, incoming requests get fired instantly.
160  // If it is not initialized, incoming requests are queued.
161  bool initialized_;
162
163  // Used to create tasks to run |Initialize| delayed on the UI thread.
164  base::WeakPtrFactory<DeviceManagementService> weak_ptr_factory_;
165
166  DISALLOW_COPY_AND_ASSIGN(DeviceManagementService);
167};
168
169}  // namespace policy
170
171#endif  // CHROME_BROWSER_POLICY_CLOUD_DEVICE_MANAGEMENT_SERVICE_H_
172