1// Copyright 2013 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_LOCAL_DISCOVERY_PRIVET_HTTP_IMPL_H_
6#define CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_HTTP_IMPL_H_
7
8#include <string>
9
10#include "base/callback.h"
11#include "base/file_util.h"
12#include "base/memory/ref_counted.h"
13#include "base/memory/weak_ptr.h"
14#include "chrome/browser/local_discovery/privet_http.h"
15#include "printing/pdf_render_settings.h"
16
17namespace local_discovery {
18
19class PrivetHTTPClientImpl;
20
21class PrivetInfoOperationImpl : public PrivetInfoOperation,
22                                public PrivetURLFetcher::Delegate {
23 public:
24  PrivetInfoOperationImpl(PrivetHTTPClientImpl* privet_client,
25                          PrivetInfoOperation::Delegate* delegate);
26  virtual ~PrivetInfoOperationImpl();
27
28  virtual void Start() OVERRIDE;
29
30  virtual PrivetHTTPClient* GetHTTPClient() OVERRIDE;
31
32  virtual void OnError(PrivetURLFetcher* fetcher,
33                       PrivetURLFetcher::ErrorType error) OVERRIDE;
34  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
35                            const base::DictionaryValue* value,
36                            bool has_error) OVERRIDE;
37
38 private:
39  PrivetHTTPClientImpl* privet_client_;
40  PrivetInfoOperation::Delegate* delegate_;
41  scoped_ptr<PrivetURLFetcher> url_fetcher_;
42};
43
44class PrivetRegisterOperationImpl
45    : public PrivetRegisterOperation,
46      public PrivetURLFetcher::Delegate,
47      public PrivetInfoOperation::Delegate,
48      public base::SupportsWeakPtr<PrivetRegisterOperationImpl> {
49 public:
50  PrivetRegisterOperationImpl(PrivetHTTPClientImpl* privet_client,
51                              const std::string& user,
52                              PrivetRegisterOperation::Delegate* delegate);
53  virtual ~PrivetRegisterOperationImpl();
54
55  virtual void Start() OVERRIDE;
56  virtual void Cancel() OVERRIDE;
57  virtual void CompleteRegistration() OVERRIDE;
58
59  virtual void OnError(PrivetURLFetcher* fetcher,
60                       PrivetURLFetcher::ErrorType error) OVERRIDE;
61
62  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
63                            const base::DictionaryValue* value,
64                            bool has_error) OVERRIDE;
65
66  virtual void OnNeedPrivetToken(
67      PrivetURLFetcher* fetcher,
68      const PrivetURLFetcher::TokenCallback& callback) OVERRIDE;
69
70  virtual void OnPrivetInfoDone(PrivetInfoOperation* operation,
71                                int http_code,
72                                const base::DictionaryValue* value) OVERRIDE;
73
74  virtual PrivetHTTPClient* GetHTTPClient() OVERRIDE;
75 private:
76  class Cancelation : public PrivetURLFetcher::Delegate {
77   public:
78    Cancelation(PrivetHTTPClientImpl* privet_client,
79                const std::string& user);
80    virtual ~Cancelation();
81
82    virtual void OnError(PrivetURLFetcher* fetcher,
83                         PrivetURLFetcher::ErrorType error) OVERRIDE;
84
85    virtual void OnParsedJson(PrivetURLFetcher* fetcher,
86                              const base::DictionaryValue* value,
87                              bool has_error) OVERRIDE;
88
89    void Cleanup();
90
91   private:
92    scoped_ptr<PrivetURLFetcher> url_fetcher_;
93  };
94
95  // Arguments is JSON value from request.
96  typedef base::Callback<void(const base::DictionaryValue&)>
97      ResponseHandler;
98
99  void StartInfoOperation();
100  void StartResponse(const base::DictionaryValue& value);
101  void GetClaimTokenResponse(const base::DictionaryValue& value);
102  void CompleteResponse(const base::DictionaryValue& value);
103
104  void SendRequest(const std::string& action);
105
106  std::string user_;
107  std::string current_action_;
108  scoped_ptr<PrivetURLFetcher> url_fetcher_;
109  PrivetRegisterOperation::Delegate* delegate_;
110  PrivetHTTPClientImpl* privet_client_;
111  ResponseHandler next_response_handler_;
112  // Required to ensure destroying completed register operations doesn't cause
113  // extraneous cancelations.
114  bool ongoing_;
115
116  scoped_ptr<PrivetInfoOperation> info_operation_;
117  std::string expected_id_;
118};
119
120// TODO(noamsml): Factor out some of this code into a PrivetBaseOperation
121class PrivetCapabilitiesOperationImpl : public PrivetCapabilitiesOperation,
122                                        public PrivetURLFetcher::Delegate {
123 public:
124  PrivetCapabilitiesOperationImpl(
125      PrivetHTTPClientImpl* privet_client,
126      PrivetCapabilitiesOperation::Delegate* delegate);
127  virtual ~PrivetCapabilitiesOperationImpl();
128  virtual void Start() OVERRIDE;
129
130  virtual PrivetHTTPClient* GetHTTPClient() OVERRIDE;
131
132  virtual void OnError(PrivetURLFetcher* fetcher,
133                       PrivetURLFetcher::ErrorType error) OVERRIDE;
134  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
135                            const base::DictionaryValue* value,
136                            bool has_error) OVERRIDE;
137  virtual void OnNeedPrivetToken(
138      PrivetURLFetcher* fetcher,
139      const PrivetURLFetcher::TokenCallback& callback) OVERRIDE;
140
141 private:
142  PrivetHTTPClientImpl* privet_client_;
143  PrivetCapabilitiesOperation::Delegate* delegate_;
144
145  scoped_ptr<PrivetURLFetcher> url_fetcher_;
146  scoped_ptr<PrivetInfoOperation> info_operation_;
147};
148
149class PrivetLocalPrintOperationImpl
150    : public PrivetLocalPrintOperation,
151      public PrivetURLFetcher::Delegate,
152      public PrivetInfoOperation::Delegate {
153 public:
154  PrivetLocalPrintOperationImpl(
155      PrivetHTTPClientImpl* privet_client,
156      PrivetLocalPrintOperation::Delegate* delegate);
157
158  virtual ~PrivetLocalPrintOperationImpl();
159  virtual void Start() OVERRIDE;
160
161  virtual void SetData(base::RefCountedBytes* data) OVERRIDE;
162
163  virtual void SetTicket(const std::string& ticket) OVERRIDE;
164
165  virtual void SetUsername(const std::string& user) OVERRIDE;
166
167  virtual void SetJobname(const std::string& jobname) OVERRIDE;
168
169  virtual void SetOffline(bool offline) OVERRIDE;
170
171  virtual void SetConversionSettings(
172      const printing::PdfRenderSettings& conversion_settings) OVERRIDE;
173
174  virtual void SetPWGRasterConverterForTesting(
175      scoped_ptr<PWGRasterConverter> pwg_raster_converter) OVERRIDE;
176
177  virtual PrivetHTTPClient* GetHTTPClient() OVERRIDE;
178
179  virtual void OnError(PrivetURLFetcher* fetcher,
180                       PrivetURLFetcher::ErrorType error) OVERRIDE;
181  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
182                            const base::DictionaryValue* value,
183                            bool has_error) OVERRIDE;
184  virtual void OnNeedPrivetToken(
185      PrivetURLFetcher* fetcher,
186      const PrivetURLFetcher::TokenCallback& callback) OVERRIDE;
187
188  virtual void OnPrivetInfoDone(PrivetInfoOperation* operation,
189                                int http_code,
190                                const base::DictionaryValue* value) OVERRIDE;
191 private:
192  typedef base::Callback<void(bool, const base::DictionaryValue* value)>
193      ResponseCallback;
194
195  void StartInitialRequest();
196  void GetCapabilities();
197  void DoCreatejob();
198  void DoSubmitdoc();
199
200  void StartConvertToPWG();
201  void StartPrinting();
202
203  void OnCapabilitiesResponse(bool has_error,
204                              const base::DictionaryValue* value);
205  void OnSubmitdocResponse(bool has_error,
206                           const base::DictionaryValue* value);
207  void OnCreatejobResponse(bool has_error,
208                           const base::DictionaryValue* value);
209  void OnPWGRasterConverted(bool success, const base::FilePath& pwg_file_path);
210
211  PrivetHTTPClientImpl* privet_client_;
212  PrivetLocalPrintOperation::Delegate* delegate_;
213
214  ResponseCallback current_response_;
215
216  std::string ticket_;
217  scoped_refptr<base::RefCountedBytes> data_;
218  base::FilePath pwg_file_path_;
219
220  bool use_pdf_;
221  bool has_capabilities_;
222  bool has_extended_workflow_;
223  bool started_;
224  bool offline_;
225  printing::PdfRenderSettings conversion_settings_;
226
227  std::string user_;
228  std::string jobname_;
229
230  std::string jobid_;
231
232  int invalid_job_retries_;
233
234  scoped_ptr<PrivetURLFetcher> url_fetcher_;
235  scoped_ptr<PrivetInfoOperation> info_operation_;
236  scoped_ptr<PWGRasterConverter> pwg_raster_converter_;
237
238  base::WeakPtrFactory<PrivetLocalPrintOperationImpl> weak_factory_;
239};
240
241class PrivetHTTPClientImpl : public PrivetHTTPClient,
242                             public PrivetInfoOperation::Delegate {
243 public:
244  PrivetHTTPClientImpl(
245      const std::string& name,
246      const net::HostPortPair& host_port,
247      net::URLRequestContextGetter* request_context);
248  virtual ~PrivetHTTPClientImpl();
249
250  virtual const base::DictionaryValue* GetCachedInfo() const OVERRIDE;
251
252  virtual scoped_ptr<PrivetRegisterOperation> CreateRegisterOperation(
253      const std::string& user,
254      PrivetRegisterOperation::Delegate* delegate) OVERRIDE;
255
256  virtual scoped_ptr<PrivetInfoOperation> CreateInfoOperation(
257      PrivetInfoOperation::Delegate* delegate) OVERRIDE;
258
259  virtual scoped_ptr<PrivetCapabilitiesOperation> CreateCapabilitiesOperation(
260      PrivetCapabilitiesOperation::Delegate* delegate) OVERRIDE;
261
262  virtual scoped_ptr<PrivetLocalPrintOperation> CreateLocalPrintOperation(
263      PrivetLocalPrintOperation::Delegate* delegate) OVERRIDE;
264
265  virtual const std::string& GetName() OVERRIDE;
266
267  scoped_ptr<PrivetURLFetcher> CreateURLFetcher(
268      const GURL& url,
269      net::URLFetcher::RequestType request_type,
270      PrivetURLFetcher::Delegate* delegate) const;
271
272  void CacheInfo(const base::DictionaryValue* cached_info);
273
274  bool HasToken() const;
275
276  void RefreshPrivetToken(
277      const PrivetURLFetcher::TokenCallback& token_callback);
278
279  virtual void OnPrivetInfoDone(PrivetInfoOperation* operation,
280                                int http_code,
281                                const base::DictionaryValue* value) OVERRIDE;
282
283 private:
284  typedef std::vector<PrivetURLFetcher::TokenCallback> TokenCallbackVector;
285  std::string name_;
286  PrivetURLFetcherFactory fetcher_factory_;
287  net::HostPortPair host_port_;
288  scoped_ptr<base::DictionaryValue> cached_info_;
289
290  scoped_ptr<PrivetInfoOperation> info_operation_;
291  TokenCallbackVector token_callbacks_;
292};
293
294}  // namespace local_discovery
295#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_PRIVET_HTTP_IMPL_H_
296