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.
5 // This file provides base classes used to implement operations for Google APIs.
7 #ifndef CHROME_BROWSER_GOOGLE_APIS_BASE_OPERATIONS_H_
8 #define CHROME_BROWSER_GOOGLE_APIS_BASE_OPERATIONS_H_
13 #include "base/callback.h"
14 #include "base/memory/weak_ptr.h"
15 #include "chrome/browser/google_apis/drive_upload_mode.h"
16 #include "chrome/browser/google_apis/gdata_errorcode.h"
17 #include "chrome/browser/google_apis/operation_registry.h"
18 #include "googleurl/src/gurl.h"
19 #include "net/url_request/url_fetcher.h"
20 #include "net/url_request/url_fetcher_delegate.h"
28 class URLRequestContextGetter
;
31 namespace google_apis
{
33 // Callback used to pass parsed JSON from ParseJson(). If parsing error occurs,
34 // then the passed argument is null.
35 typedef base::Callback
<void(scoped_ptr
<base::Value
> value
)> ParseJsonCallback
;
37 // Callback used for DownloadOperation and ResumeUploadOperation.
38 typedef base::Callback
<void(int64 progress
, int64 total
)> ProgressCallback
;
40 // Parses JSON passed in |json| on blocking pool. Runs |callback| on the calling
41 // thread when finished with either success or failure.
42 // The callback must not be null.
43 void ParseJson(const std::string
& json
, const ParseJsonCallback
& callback
);
45 //======================= AuthenticatedOperationInterface ======================
47 // An interface class for implementing an operation which requires OAuth2
49 class AuthenticatedOperationInterface
{
51 // Called when re-authentication is required. See Start() for details.
52 typedef base::Callback
<void(AuthenticatedOperationInterface
* operation
)>
53 ReAuthenticateCallback
;
55 virtual ~AuthenticatedOperationInterface() {}
57 // Starts the operation with |access_token|. User-Agent header will be set
58 // to |custom_user_agent| if the value is not empty.
60 // |callback| is called when re-authentication is needed for a certain
61 // number of times (see kMaxReAuthenticateAttemptsPerOperation in .cc).
62 // The callback should retry by calling Start() again with a new access
63 // token, or just call OnAuthFailed() if a retry is not attempted.
64 // |callback| must not be null.
65 virtual void Start(const std::string
& access_token
,
66 const std::string
& custom_user_agent
,
67 const ReAuthenticateCallback
& callback
) = 0;
69 // Invoked when the authentication failed with an error code |code|.
70 virtual void OnAuthFailed(GDataErrorCode code
) = 0;
72 // Gets a weak pointer to this operation object. Since operations may be
73 // deleted when it is canceled by user action, for posting asynchronous tasks
74 // on the authentication operation object, weak pointers have to be used.
75 // TODO(kinaba): crbug.com/134814 use more clean life time management than
76 // using weak pointers, while deprecating OperationRegistry.
77 virtual base::WeakPtr
<AuthenticatedOperationInterface
> GetWeakPtr() = 0;
80 //============================ UrlFetchOperationBase ===========================
82 // Callback type for getting the content from URLFetcher::GetResponseAsString().
83 typedef base::Callback
<void(
85 scoped_ptr
<std::string
> content
)> GetContentCallback
;
87 // Base class for operations that are fetching URLs.
88 class UrlFetchOperationBase
: public AuthenticatedOperationInterface
,
89 public OperationRegistry::Operation
,
90 public net::URLFetcherDelegate
{
92 // AuthenticatedOperationInterface overrides.
93 virtual void Start(const std::string
& access_token
,
94 const std::string
& custom_user_agent
,
95 const ReAuthenticateCallback
& callback
) OVERRIDE
;
96 virtual base::WeakPtr
<AuthenticatedOperationInterface
> GetWeakPtr() OVERRIDE
;
99 explicit UrlFetchOperationBase(
100 OperationRegistry
* registry
,
101 net::URLRequestContextGetter
* url_request_context_getter
);
102 // Use this constructor when you need to implement operations that take a
103 // drive file path (ex. for downloading and uploading).
104 // |url_request_context_getter| is used to initialize URLFetcher.
105 // TODO(satorux): Remove the drive file path hack. crbug.com/163296
106 UrlFetchOperationBase(
107 OperationRegistry
* registry
,
108 net::URLRequestContextGetter
* url_request_context_getter
,
110 const base::FilePath
& drive_file_path
);
111 virtual ~UrlFetchOperationBase();
113 // Gets URL for the request.
114 virtual GURL
GetURL() const = 0;
116 // Returns the request type. A derived class should override this method
117 // for a request type other than HTTP GET.
118 virtual net::URLFetcher::RequestType
GetRequestType() const;
120 // Returns the extra HTTP headers for the request. A derived class should
121 // override this method to specify any extra headers needed for the request.
122 virtual std::vector
<std::string
> GetExtraRequestHeaders() const;
124 // Used by a derived class to add any content data to the request.
125 // Returns true if |upload_content_type| and |upload_content| are updated
126 // with the content type and data for the request.
127 virtual bool GetContentData(std::string
* upload_content_type
,
128 std::string
* upload_content
);
130 // Invoked by OnURLFetchComplete when the operation completes without an
131 // authentication error. Must be implemented by a derived class.
132 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) = 0;
134 // Invoked when it needs to notify the status. Chunked operations that
135 // constructs a logically single operation from multiple physical operations
136 // should notify resume/suspend instead of start/finish.
137 virtual void NotifyStartToOperationRegistry();
138 virtual void NotifySuccessToOperationRegistry();
140 // Invoked by this base class upon an authentication error or cancel by
141 // an user operation. Must be implemented by a derived class.
142 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) = 0;
144 // Invoked when ProcessURLFetchResults() is completed.
145 void OnProcessURLFetchResultsComplete(bool result
);
147 // Returns an appropriate GDataErrorCode based on the HTTP response code and
148 // the status of the URLFetcher.
149 static GDataErrorCode
GetErrorCode(const net::URLFetcher
* source
);
151 // By default, no temporary file will be saved. Derived classes can set
152 // this to true in their constructors, if they want to save the downloaded
153 // content to a temporary file.
154 void set_save_temp_file(bool save_temp_file
) {
155 save_temp_file_
= save_temp_file
;
158 // By default, no file will be saved. Derived classes can set an output
159 // file path in their constructors, if they want to save the downloaded
160 // content to a file at a specific path.
161 void set_output_file_path(const base::FilePath
& output_file_path
) {
162 output_file_path_
= output_file_path
;
166 // OperationRegistry::Operation overrides.
167 virtual void DoCancel() OVERRIDE
;
169 // URLFetcherDelegate overrides.
170 virtual void OnURLFetchComplete(const net::URLFetcher
* source
) OVERRIDE
;
172 // AuthenticatedOperationInterface overrides.
173 virtual void OnAuthFailed(GDataErrorCode code
) OVERRIDE
;
175 net::URLRequestContextGetter
* url_request_context_getter_
;
176 ReAuthenticateCallback re_authenticate_callback_
;
177 int re_authenticate_count_
;
178 scoped_ptr
<net::URLFetcher
> url_fetcher_
;
181 bool save_temp_file_
;
182 base::FilePath output_file_path_
;
184 // WeakPtrFactory bound to the UI thread.
185 // Note: This should remain the last member so it'll be destroyed and
186 // invalidate its weak pointers before any other members are destroyed.
187 base::WeakPtrFactory
<UrlFetchOperationBase
> weak_ptr_factory_
;
190 //============================ EntryActionOperation ============================
192 // Callback type for Delete/Move DocumentServiceInterface calls.
193 typedef base::Callback
<void(GDataErrorCode error
)> EntryActionCallback
;
195 // This class performs a simple action over a given entry (document/file).
196 // It is meant to be used for operations that return no JSON blobs.
197 class EntryActionOperation
: public UrlFetchOperationBase
{
199 // |url_request_context_getter| is used to initialize URLFetcher.
200 // |callback| must not be null.
201 EntryActionOperation(
202 OperationRegistry
* registry
,
203 net::URLRequestContextGetter
* url_request_context_getter
,
204 const EntryActionCallback
& callback
);
205 virtual ~EntryActionOperation();
208 // Overridden from UrlFetchOperationBase.
209 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
210 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) OVERRIDE
;
213 const EntryActionCallback callback_
;
215 DISALLOW_COPY_AND_ASSIGN(EntryActionOperation
);
218 //============================== GetDataOperation ==============================
220 // Callback type for DocumentServiceInterface::GetResourceList.
221 // Note: json_data argument should be passed using base::Passed(&json_data), not
223 typedef base::Callback
<void(GDataErrorCode error
,
224 scoped_ptr
<base::Value
> json_data
)> GetDataCallback
;
226 // This class performs the operation for fetching and converting the fetched
227 // content into a base::Value.
228 class GetDataOperation
: public UrlFetchOperationBase
{
230 // |callback| must not be null.
231 GetDataOperation(OperationRegistry
* registry
,
232 net::URLRequestContextGetter
* url_request_context_getter
,
233 const GetDataCallback
& callback
);
234 virtual ~GetDataOperation();
236 // Parses JSON response.
237 void ParseResponse(GDataErrorCode fetch_error_code
, const std::string
& data
);
240 // UrlFetchOperationBase overrides.
241 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
242 virtual void RunCallbackOnPrematureFailure(
243 GDataErrorCode fetch_error_code
) OVERRIDE
;
246 // Runs |callback_| with the given parameters.
247 void RunCallbackOnSuccess(GDataErrorCode fetch_error_code
,
248 scoped_ptr
<base::Value
> value
);
251 // Called when ParseJsonOnBlockingPool() is completed.
252 void OnDataParsed(GDataErrorCode fetch_error_code
,
253 scoped_ptr
<base::Value
> value
);
255 const GetDataCallback callback_
;
257 // Note: This should remain the last member so it'll be destroyed and
258 // invalidate its weak pointers before any other members are destroyed.
259 base::WeakPtrFactory
<GetDataOperation
> weak_ptr_factory_
;
260 DISALLOW_COPY_AND_ASSIGN(GetDataOperation
);
264 //=========================== InitiateUploadOperation ==========================
266 // Callback type for DocumentServiceInterface::InitiateUpload.
267 typedef base::Callback
<void(GDataErrorCode error
,
268 const GURL
& upload_url
)> InitiateUploadCallback
;
270 // This class provides base implementation for performing the operation for
271 // initiating the upload of a file.
272 // |callback| will be called with the obtained upload URL. The URL will be
273 // used with operations for resuming the file uploading.
275 // Here's the flow of uploading:
276 // 1) Get the upload URL with a class inheriting InitiateUploadOperationBase.
277 // 2) Upload the first 512KB (see kUploadChunkSize in drive_uploader.cc)
278 // of the target file to the upload URL
279 // 3) If there is more data to upload, go to 2).
281 class InitiateUploadOperationBase
: public UrlFetchOperationBase
{
283 // |callback| will be called with the upload URL, where upload data is
284 // uploaded to with ResumeUploadOperation.
285 // |callback| must not be null.
286 // |content_type| and |content_length| should be the attributes of the
288 InitiateUploadOperationBase(
289 OperationRegistry
* registry
,
290 net::URLRequestContextGetter
* url_request_context_getter
,
291 const InitiateUploadCallback
& callback
,
292 const base::FilePath
& drive_file_path
,
293 const std::string
& content_type
,
294 int64 content_length
);
295 virtual ~InitiateUploadOperationBase();
297 // UrlFetchOperationBase overrides.
298 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
299 virtual void NotifySuccessToOperationRegistry() OVERRIDE
;
300 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) OVERRIDE
;
301 virtual std::vector
<std::string
> GetExtraRequestHeaders() const OVERRIDE
;
304 const InitiateUploadCallback callback_
;
305 const base::FilePath drive_file_path_
;
306 const std::string content_type_
;
307 const int64 content_length_
;
309 DISALLOW_COPY_AND_ASSIGN(InitiateUploadOperationBase
);
312 //========================== UploadRangeOperationBase ==========================
314 // Struct for response to ResumeUpload and GetUploadStatus.
315 struct UploadRangeResponse
{
316 UploadRangeResponse();
317 UploadRangeResponse(GDataErrorCode code
,
318 int64 start_position_received
,
319 int64 end_position_received
);
320 ~UploadRangeResponse();
323 // The values of "Range" header returned from the server. The values are
324 // used to continue uploading more data. These are set to -1 if an upload
326 // |start_position_received| is inclusive and |end_position_received| is
327 // exclusive to follow the common C++ manner, although the response from
328 // the server has "Range" header in inclusive format at both sides.
329 int64 start_position_received
;
330 int64 end_position_received
;
333 // Base class for a URL fetch request expecting the response containing the
334 // current uploading range. This class processes the response containing
335 // "Range" header and invoke OnRangeOperationComplete.
336 class UploadRangeOperationBase
: public UrlFetchOperationBase
{
338 // |upload_location| is the URL of where to upload the file to.
339 // |drive_file_path| is the path to the file seen in the UI. Not necessary
340 // for resuming an upload, but used for adding an entry to OperationRegistry.
341 // TODO(satorux): Remove the drive file path hack. crbug.com/163296
342 UploadRangeOperationBase(
343 OperationRegistry
* registry
,
344 net::URLRequestContextGetter
* url_request_context_getter
,
345 const UploadMode upload_mode
,
346 const base::FilePath
& drive_file_path
,
347 const GURL
& upload_url
);
348 virtual ~UploadRangeOperationBase();
350 // UrlFetchOperationBase overrides.
351 virtual GURL
GetURL() const OVERRIDE
;
352 virtual net::URLFetcher::RequestType
GetRequestType() const OVERRIDE
;
353 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
354 virtual void NotifyStartToOperationRegistry() OVERRIDE
;
355 virtual void NotifySuccessToOperationRegistry() OVERRIDE
;
356 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) OVERRIDE
;
358 // This method will be called when the operation is done, regardless of
359 // whether it is succeeded or failed.
361 // 1) If there is more data to upload, |code| of |response| is set to
362 // HTTP_RESUME_INCOMPLETE, and positions are set appropriately. Also, |value|
363 // will be set to NULL.
364 // 2) If the upload is complete, |code| is set to HTTP_CREATED for a new file
365 // or HTTP_SUCCESS for an existing file. Positions are set to -1, and |value|
366 // is set to a parsed JSON value representing the uploaded file.
367 // 3) If a premature failure is found, |code| is set to a value representing
368 // the situation. Positions are set to 0, and |value| is set to NULL.
370 // See also the comments for UploadRangeResponse.
371 // Note: Subclasses should have responsibility to run some callback
372 // in this method to notify the finish status to its clients (or ignore it
373 // under its responsibility).
374 virtual void OnRangeOperationComplete(
375 const UploadRangeResponse
& response
, scoped_ptr
<base::Value
> value
) = 0;
378 // Called when ParseJson() is completed.
379 void OnDataParsed(GDataErrorCode code
, scoped_ptr
<base::Value
> value
);
381 const UploadMode upload_mode_
;
382 const base::FilePath drive_file_path_
;
383 const GURL upload_url_
;
385 bool last_chunk_completed_
;
387 // Note: This should remain the last member so it'll be destroyed and
388 // invalidate its weak pointers before any other members are destroyed.
389 base::WeakPtrFactory
<UploadRangeOperationBase
> weak_ptr_factory_
;
390 DISALLOW_COPY_AND_ASSIGN(UploadRangeOperationBase
);
393 //========================== ResumeUploadOperationBase =========================
395 // This class performs the operation for resuming the upload of a file.
396 // More specifically, this operation uploads a chunk of data carried in |buf|
397 // of ResumeUploadResponseBase. This class is designed to share the
398 // implementation of upload resuming between GData WAPI and Drive API v2.
399 // The subclasses should implement OnRangeOperationComplete inherited by
400 // UploadRangeOperationBase, because the type of the response should be
401 // different (although the format in the server response is JSON).
402 class ResumeUploadOperationBase
: public UploadRangeOperationBase
{
404 // |start_position| is the start of range of contents currently stored in
405 // |buf|. |end_position| is the end of range of contents currently stared in
406 // |buf|. This is exclusive. For instance, if you are to upload the first
407 // 500 bytes of data, |start_position| is 0 and |end_position| is 500.
408 // |content_length| and |content_type| are the length and type of the
409 // file content to be uploaded respectively.
410 // |buf| holds current content to be uploaded.
411 // See also UploadRangeOperationBase's comment for remaining parameters
413 ResumeUploadOperationBase(
414 OperationRegistry
* registry
,
415 net::URLRequestContextGetter
* url_request_context_getter
,
416 UploadMode upload_mode
,
417 const base::FilePath
& drive_file_path
,
418 const GURL
& upload_location
,
419 int64 start_position
,
421 int64 content_length
,
422 const std::string
& content_type
,
423 const scoped_refptr
<net::IOBuffer
>& buf
);
424 virtual ~ResumeUploadOperationBase();
426 // UrlFetchOperationBase overrides.
427 virtual std::vector
<std::string
> GetExtraRequestHeaders() const OVERRIDE
;
428 virtual bool GetContentData(std::string
* upload_content_type
,
429 std::string
* upload_content
) OVERRIDE
;
431 // content::UrlFetcherDelegate overrides.
432 virtual void OnURLFetchUploadProgress(const net::URLFetcher
* source
,
433 int64 current
, int64 total
) OVERRIDE
;
436 // The parameters for the request. See ResumeUploadParams for the details.
437 const int64 start_position_
;
438 const int64 end_position_
;
439 const int64 content_length_
;
440 const std::string content_type_
;
441 const scoped_refptr
<net::IOBuffer
> buf_
;
443 DISALLOW_COPY_AND_ASSIGN(ResumeUploadOperationBase
);
446 //============================ DownloadFileOperation ===========================
448 // Callback type for DownloadHostedDocument/DownloadFile
449 // DocumentServiceInterface calls.
450 typedef base::Callback
<void(GDataErrorCode error
,
451 const base::FilePath
& temp_file
)>
452 DownloadActionCallback
;
454 // This class performs the operation for downloading of a given document/file.
455 class DownloadFileOperation
: public UrlFetchOperationBase
{
457 // download_action_callback:
458 // This callback is called when the download is complete. Must not be null.
460 // get_content_callback:
461 // This callback is called when some part of the content is
462 // read. Used to read the download content progressively. May be null.
464 // progress_callback:
465 // This callback is called for periodically reporting the number of bytes
466 // downloaded so far. May be null.
469 // Specifies the target file to download.
472 // Specifies the drive path of the target file. Shown in UI.
473 // TODO(satorux): Remove the drive file path hack. crbug.com/163296
476 // Specifies the file path to save the downloaded file.
478 DownloadFileOperation(
479 OperationRegistry
* registry
,
480 net::URLRequestContextGetter
* url_request_context_getter
,
481 const DownloadActionCallback
& download_action_callback
,
482 const GetContentCallback
& get_content_callback
,
483 const ProgressCallback
& progress_callback
,
484 const GURL
& download_url
,
485 const base::FilePath
& drive_file_path
,
486 const base::FilePath
& output_file_path
);
487 virtual ~DownloadFileOperation();
490 // UrlFetchOperationBase overrides.
491 virtual GURL
GetURL() const OVERRIDE
;
492 virtual void ProcessURLFetchResults(const net::URLFetcher
* source
) OVERRIDE
;
493 virtual void RunCallbackOnPrematureFailure(GDataErrorCode code
) OVERRIDE
;
495 // net::URLFetcherDelegate overrides.
496 virtual void OnURLFetchDownloadProgress(const net::URLFetcher
* source
,
497 int64 current
, int64 total
) OVERRIDE
;
498 virtual bool ShouldSendDownloadData() OVERRIDE
;
499 virtual void OnURLFetchDownloadData(
500 const net::URLFetcher
* source
,
501 scoped_ptr
<std::string
> download_data
) OVERRIDE
;
504 const DownloadActionCallback download_action_callback_
;
505 const GetContentCallback get_content_callback_
;
506 const ProgressCallback progress_callback_
;
507 const GURL download_url_
;
509 DISALLOW_COPY_AND_ASSIGN(DownloadFileOperation
);
512 } // namespace google_apis
514 #endif // CHROME_BROWSER_GOOGLE_APIS_BASE_OPERATIONS_H_