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_DRIVE_DRIVE_UPLOADER_H_
6#define CHROME_BROWSER_DRIVE_DRIVE_UPLOADER_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/callback_forward.h"
12#include "base/memory/ref_counted.h"
13#include "base/memory/weak_ptr.h"
14#include "chrome/browser/drive/drive_service_interface.h"
15#include "google_apis/drive/gdata_errorcode.h"
16#include "google_apis/drive/gdata_wapi_parser.h"
17
18class GURL;
19
20namespace base {
21class FilePath;
22class TaskRunner;
23}
24
25namespace google_apis {
26struct UploadRangeResponse;
27}
28
29namespace drive {
30class DriveServiceInterface;
31
32// Callback to be invoked once the upload has completed.
33// |upload_location| will be returned when the uploading process is started but
34// terminated before the completion due to some errors. It can be used to
35// resume it.
36typedef base::Callback<void(
37    google_apis::GDataErrorCode error,
38    const GURL& upload_location,
39    scoped_ptr<google_apis::ResourceEntry> resource_entry)>
40    UploadCompletionCallback;
41
42class DriveUploaderInterface {
43 public:
44  virtual ~DriveUploaderInterface() {}
45
46  // Uploads a new file to a directory specified by |upload_location|.
47  // Returns a callback for cancelling the uploading job.
48  //
49  // parent_resource_id:
50  //   resource id of the destination directory.
51  //
52  // local_file_path:
53  //   The path to the local file to be uploaded.
54  //
55  // title:
56  //   The title (file name) of the file to be uploaded.
57  //
58  // content_type:
59  //   The content type of the file to be uploaded.
60  //
61  // callback:
62  //   Called when an upload is done regardless of it was successful or not.
63  //   Must not be null.
64  //
65  // progress_callback:
66  //   Periodically called back with the total number of bytes sent so far.
67  //   May be null if the information is not needed.
68  virtual google_apis::CancelCallback UploadNewFile(
69      const std::string& parent_resource_id,
70      const base::FilePath& local_file_path,
71      const std::string& title,
72      const std::string& content_type,
73      const UploadCompletionCallback& callback,
74      const google_apis::ProgressCallback& progress_callback) = 0;
75
76  // Uploads an existing file (a file that already exists on Drive).
77  //
78  // See comments at UploadNewFile about common parameters and the return value.
79  //
80  // resource_id:
81  //   resource id of the existing file to be overwritten.
82  //
83  // etag:
84  //   Expected ETag for the destination file. If it does not match, the upload
85  //   fails with UPLOAD_ERROR_CONFLICT.
86  //   If |etag| is empty, the test is skipped.
87  virtual google_apis::CancelCallback UploadExistingFile(
88      const std::string& resource_id,
89      const base::FilePath& local_file_path,
90      const std::string& content_type,
91      const std::string& etag,
92      const UploadCompletionCallback& callback,
93      const google_apis::ProgressCallback& progress_callback) = 0;
94
95  // Resumes the uploading process terminated before the completion.
96  // |upload_location| should be the one returned via UploadCompletionCallback
97  // for previous invocation. |drive_file_path|, |local_file_path| and
98  // |content_type| must be set to the same ones for previous invocation.
99  //
100  // See comments at UploadNewFile about common parameters and the return value.
101  virtual google_apis::CancelCallback ResumeUploadFile(
102      const GURL& upload_location,
103      const base::FilePath& local_file_path,
104      const std::string& content_type,
105      const UploadCompletionCallback& callback,
106      const google_apis::ProgressCallback& progress_callback) = 0;
107};
108
109class DriveUploader : public DriveUploaderInterface {
110 public:
111  DriveUploader(DriveServiceInterface* drive_service,
112                base::TaskRunner* blocking_task_runner);
113  virtual ~DriveUploader();
114
115  // DriveUploaderInterface overrides.
116  virtual google_apis::CancelCallback UploadNewFile(
117      const std::string& parent_resource_id,
118      const base::FilePath& local_file_path,
119      const std::string& title,
120      const std::string& content_type,
121      const UploadCompletionCallback& callback,
122      const google_apis::ProgressCallback& progress_callback) OVERRIDE;
123  virtual google_apis::CancelCallback UploadExistingFile(
124      const std::string& resource_id,
125      const base::FilePath& local_file_path,
126      const std::string& content_type,
127      const std::string& etag,
128      const UploadCompletionCallback& callback,
129      const google_apis::ProgressCallback& progress_callback) OVERRIDE;
130  virtual google_apis::CancelCallback ResumeUploadFile(
131      const GURL& upload_location,
132      const base::FilePath& local_file_path,
133      const std::string& content_type,
134      const UploadCompletionCallback& callback,
135      const google_apis::ProgressCallback& progress_callback) OVERRIDE;
136
137 private:
138  struct UploadFileInfo;
139  typedef base::Callback<void(scoped_ptr<UploadFileInfo> upload_file_info)>
140      StartInitiateUploadCallback;
141
142  // Starts uploading a file with |upload_file_info|.
143  google_apis::CancelCallback StartUploadFile(
144      scoped_ptr<UploadFileInfo> upload_file_info,
145      const StartInitiateUploadCallback& start_initiate_upload_callback);
146  void StartUploadFileAfterGetFileSize(
147      scoped_ptr<UploadFileInfo> upload_file_info,
148      const StartInitiateUploadCallback& start_initiate_upload_callback,
149      bool get_file_size_result);
150
151  // Starts to initiate the new file uploading.
152  // Upon completion, OnUploadLocationReceived should be called.
153  void StartInitiateUploadNewFile(
154      const std::string& parent_resource_id,
155      const std::string& title,
156      scoped_ptr<UploadFileInfo> upload_file_info);
157
158  // Starts to initiate the existing file uploading.
159  // Upon completion, OnUploadLocationReceived should be called.
160  void StartInitiateUploadExistingFile(
161      const std::string& resource_id,
162      const std::string& etag,
163      scoped_ptr<UploadFileInfo> upload_file_info);
164
165  // DriveService callback for InitiateUpload.
166  void OnUploadLocationReceived(scoped_ptr<UploadFileInfo> upload_file_info,
167                                google_apis::GDataErrorCode code,
168                                const GURL& upload_location);
169
170  // Starts to get the current upload status for the file uploading.
171  // Upon completion, OnUploadRangeResponseReceived should be called.
172  void StartGetUploadStatus(scoped_ptr<UploadFileInfo> upload_file_info);
173
174  // Uploads the next chunk of data from the file.
175  void UploadNextChunk(scoped_ptr<UploadFileInfo> upload_file_info);
176
177  // DriveService callback for ResumeUpload.
178  void OnUploadRangeResponseReceived(
179      scoped_ptr<UploadFileInfo> upload_file_info,
180      const google_apis::UploadRangeResponse& response,
181      scoped_ptr<google_apis::ResourceEntry> entry);
182  void OnUploadProgress(const google_apis::ProgressCallback& callback,
183                        int64 start_position,
184                        int64 total_size,
185                        int64 progress_of_chunk,
186                        int64 total_of_chunk);
187
188  // Handle failed uploads.
189  void UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info,
190                    google_apis::GDataErrorCode error);
191
192  // The lifetime of this object should be guaranteed to exceed that of the
193  // DriveUploader instance.
194  DriveServiceInterface* drive_service_;  // Not owned by this class.
195
196  scoped_refptr<base::TaskRunner> blocking_task_runner_;
197
198  // Note: This should remain the last member so it'll be destroyed and
199  // invalidate its weak pointers before any other members are destroyed.
200  base::WeakPtrFactory<DriveUploader> weak_ptr_factory_;
201  DISALLOW_COPY_AND_ASSIGN(DriveUploader);
202};
203
204}  // namespace drive
205
206#endif  // CHROME_BROWSER_DRIVE_DRIVE_UPLOADER_H_
207