Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(509)

Side by Side Diff: chrome/browser/google_apis/drive_uploader.cc

Issue 12207075: Split InitiateUpload method into two. (Closed) Base URL: http://git.chromium.org/chromium/src.git@b148632_extract_initiate_upload_operation_base
Patch Set: Rebase Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/google_apis/drive_uploader.h" 5 #include "chrome/browser/google_apis/drive_uploader.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 27 matching lines...) Expand all
38 38
39 } // namespace 39 } // namespace
40 40
41 namespace google_apis { 41 namespace google_apis {
42 42
43 // Structure containing current upload information of file, passed between 43 // Structure containing current upload information of file, passed between
44 // DriveServiceInterface methods and callbacks. 44 // DriveServiceInterface methods and callbacks.
45 struct DriveUploader::UploadFileInfo { 45 struct DriveUploader::UploadFileInfo {
46 UploadFileInfo(scoped_refptr<base::SequencedTaskRunner> task_runner, 46 UploadFileInfo(scoped_refptr<base::SequencedTaskRunner> task_runner,
47 UploadMode upload_mode, 47 UploadMode upload_mode,
48 const GURL& initial_upload_location, 48 const FilePath& drive_path,
49 const base::FilePath& drive_path, 49 const FilePath& local_path,
50 const base::FilePath& local_path,
51 const std::string& title,
52 const std::string& content_type, 50 const std::string& content_type,
53 const std::string& etag,
54 const UploadCompletionCallback& callback) 51 const UploadCompletionCallback& callback)
55 : upload_mode(upload_mode), 52 : upload_mode(upload_mode),
56 initial_upload_location(initial_upload_location),
57 drive_path(drive_path), 53 drive_path(drive_path),
58 file_path(local_path), 54 file_path(local_path),
59 title(title),
60 content_type(content_type), 55 content_type(content_type),
61 etag(etag),
62 completion_callback(callback), 56 completion_callback(callback),
63 content_length(0), 57 content_length(0),
64 next_send_position(0), 58 next_send_position(0),
65 file_stream(new net::FileStream(NULL)), 59 file_stream(new net::FileStream(NULL)),
66 buf(new net::IOBuffer(kUploadChunkSize)), 60 buf(new net::IOBuffer(kUploadChunkSize)),
67 blocking_task_runner(task_runner), 61 blocking_task_runner(task_runner),
68 power_save_blocker(content::PowerSaveBlocker::Create( 62 power_save_blocker(content::PowerSaveBlocker::Create(
69 content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, 63 content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
70 "Upload in progress")) { 64 "Upload in progress")) {
71 } 65 }
72 66
73 ~UploadFileInfo() { 67 ~UploadFileInfo() {
74 blocking_task_runner->DeleteSoon(FROM_HERE, file_stream.release()); 68 blocking_task_runner->DeleteSoon(FROM_HERE, file_stream.release());
75 } 69 }
76 70
77 // Bytes left to upload. 71 // Bytes left to upload.
78 int64 SizeRemaining() const { 72 int64 SizeRemaining() const {
79 DCHECK(content_length >= next_send_position); 73 DCHECK(content_length >= next_send_position);
80 return content_length - next_send_position; 74 return content_length - next_send_position;
81 } 75 }
82 76
83 // Useful for printf debugging. 77 // Useful for printf debugging.
84 std::string DebugString() const { 78 std::string DebugString() const {
85 return "title=[" + title + 79 return "file_path=[" + file_path.AsUTF8Unsafe() +
86 "], file_path=[" + file_path.AsUTF8Unsafe() +
87 "], content_type=[" + content_type + 80 "], content_type=[" + content_type +
88 "], content_length=[" + base::UintToString(content_length) + 81 "], content_length=[" + base::UintToString(content_length) +
89 "], drive_path=[" + drive_path.AsUTF8Unsafe() + 82 "], drive_path=[" + drive_path.AsUTF8Unsafe() +
90 "]"; 83 "]";
91 } 84 }
92 85
93 // Whether this is uploading a new file or updating an existing file. 86 // Whether this is uploading a new file or updating an existing file.
94 const UploadMode upload_mode; 87 const UploadMode upload_mode;
95 88
96 // Location URL used to get |upload_location| with InitiateUpload.
97 const GURL initial_upload_location;
98
99 // Final path in gdata. Looks like /special/drive/MyFolder/MyFile. 89 // Final path in gdata. Looks like /special/drive/MyFolder/MyFile.
100 const base::FilePath drive_path; 90 const base::FilePath drive_path;
101 91
102 // The local file path of the file to be uploaded. 92 // The local file path of the file to be uploaded.
103 const base::FilePath file_path; 93 const base::FilePath file_path;
104 94
105 // Title to be used for file to be uploaded.
106 const std::string title;
107
108 // Content-Type of file. 95 // Content-Type of file.
109 const std::string content_type; 96 const std::string content_type;
110 97
111 const std::string etag;
112
113 // Callback to be invoked once the upload has finished. 98 // Callback to be invoked once the upload has finished.
114 const UploadCompletionCallback completion_callback; 99 const UploadCompletionCallback completion_callback;
115 100
116 // Location URL where file is to be uploaded to, returned from 101 // Location URL where file is to be uploaded to, returned from
117 // InitiateUpload. Used for the subsequent ResumeUpload requests. 102 // InitiateUpload. Used for the subsequent ResumeUpload requests.
118 GURL upload_location; 103 GURL upload_location;
119 104
120 // Header content-Length. 105 // Header content-Length.
121 int64 content_length; 106 int64 content_length;
122 107
(...skipping 22 matching lines...) Expand all
145 DriveUploader::DriveUploader(DriveServiceInterface* drive_service) 130 DriveUploader::DriveUploader(DriveServiceInterface* drive_service)
146 : drive_service_(drive_service), 131 : drive_service_(drive_service),
147 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 132 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
148 base::SequencedWorkerPool* blocking_pool = BrowserThread::GetBlockingPool(); 133 base::SequencedWorkerPool* blocking_pool = BrowserThread::GetBlockingPool();
149 blocking_task_runner_ = blocking_pool->GetSequencedTaskRunner( 134 blocking_task_runner_ = blocking_pool->GetSequencedTaskRunner(
150 blocking_pool->GetSequenceToken()); 135 blocking_pool->GetSequenceToken());
151 } 136 }
152 137
153 DriveUploader::~DriveUploader() {} 138 DriveUploader::~DriveUploader() {}
154 139
155 void DriveUploader::UploadNewFile(const GURL& upload_location, 140 void DriveUploader::UploadNewFile(const GURL& parent_upload_url,
156 const base::FilePath& drive_file_path, 141 const base::FilePath& drive_file_path,
157 const base::FilePath& local_file_path, 142 const base::FilePath& local_file_path,
158 const std::string& title, 143 const std::string& title,
159 const std::string& content_type, 144 const std::string& content_type,
160 const UploadCompletionCallback& callback) { 145 const UploadCompletionCallback& callback) {
161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
162 DCHECK(!upload_location.is_empty()); 147 DCHECK(!parent_upload_url.is_empty());
163 DCHECK(!drive_file_path.empty()); 148 DCHECK(!drive_file_path.empty());
164 DCHECK(!local_file_path.empty()); 149 DCHECK(!local_file_path.empty());
165 DCHECK(!title.empty()); 150 DCHECK(!title.empty());
166 DCHECK(!content_type.empty()); 151 DCHECK(!content_type.empty());
167 DCHECK(!callback.is_null()); 152 DCHECK(!callback.is_null());
168 153
169 StartUploadFile(scoped_ptr<UploadFileInfo>(new UploadFileInfo( 154 StartUploadFile(
170 blocking_task_runner_, 155 scoped_ptr<UploadFileInfo>(new UploadFileInfo(blocking_task_runner_,
171 UPLOAD_NEW_FILE, 156 UPLOAD_NEW_FILE,
172 upload_location, 157 drive_file_path,
173 drive_file_path, 158 local_file_path,
174 local_file_path, 159 content_type,
175 title, 160 callback)),
176 content_type, 161 base::Bind(&DriveUploader::StartInitiateUploadNewFile,
177 "", // etag 162 weak_ptr_factory_.GetWeakPtr(),
178 callback 163 parent_upload_url,
179 ))); 164 title));
180 } 165 }
181 166
182 void DriveUploader::UploadExistingFile( 167 void DriveUploader::UploadExistingFile(
183 const GURL& upload_location, 168 const GURL& upload_url,
184 const base::FilePath& drive_file_path, 169 const base::FilePath& drive_file_path,
185 const base::FilePath& local_file_path, 170 const base::FilePath& local_file_path,
186 const std::string& content_type, 171 const std::string& content_type,
187 const std::string& etag, 172 const std::string& etag,
188 const UploadCompletionCallback& callback) { 173 const UploadCompletionCallback& callback) {
189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
190 DCHECK(!upload_location.is_empty()); 175 DCHECK(!upload_url.is_empty());
191 DCHECK(!drive_file_path.empty()); 176 DCHECK(!drive_file_path.empty());
192 DCHECK(!local_file_path.empty()); 177 DCHECK(!local_file_path.empty());
193 DCHECK(!content_type.empty()); 178 DCHECK(!content_type.empty());
194 DCHECK(!callback.is_null()); 179 DCHECK(!callback.is_null());
195 180
196 StartUploadFile(scoped_ptr<UploadFileInfo>(new UploadFileInfo( 181 StartUploadFile(
197 blocking_task_runner_, 182 scoped_ptr<UploadFileInfo>(new UploadFileInfo(blocking_task_runner_,
198 UPLOAD_EXISTING_FILE, 183 UPLOAD_EXISTING_FILE,
199 upload_location, 184 drive_file_path,
200 drive_file_path, 185 local_file_path,
201 local_file_path, 186 content_type,
202 "", // title : not necessary for update of an existing file. 187 callback)),
203 content_type, 188 base::Bind(&DriveUploader::StartInitiateUploadExistingFile,
204 etag, 189 weak_ptr_factory_.GetWeakPtr(),
205 callback 190 upload_url,
206 ))); 191 etag));
207 } 192 }
208 193
209 void DriveUploader::StartUploadFile( 194 void DriveUploader::StartUploadFile(
210 scoped_ptr<UploadFileInfo> upload_file_info) { 195 scoped_ptr<UploadFileInfo> upload_file_info,
196 const StartInitiateUploadCallback& start_initiate_upload_callback) {
211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
212 DVLOG(1) << "Uploading file: " << upload_file_info->DebugString(); 198 DVLOG(1) << "Uploading file: " << upload_file_info->DebugString();
213 199
214 // Passing a raw net::FileStream* to the blocking pool is safe, because it is 200 // Passing a raw net::FileStream* to the blocking pool is safe, because it is
215 // owned by |upload_file_info| in the reply callback. 201 // owned by |upload_file_info| in the reply callback.
216 UploadFileInfo* info_ptr = upload_file_info.get(); 202 UploadFileInfo* info_ptr = upload_file_info.get();
217 base::PostTaskAndReplyWithResult( 203 base::PostTaskAndReplyWithResult(
218 blocking_task_runner_.get(), 204 blocking_task_runner_.get(),
219 FROM_HERE, 205 FROM_HERE,
220 base::Bind(&OpenFileStreamAndGetSizeOnBlockingPool, 206 base::Bind(&OpenFileStreamAndGetSizeOnBlockingPool,
221 info_ptr->file_stream.get(), 207 info_ptr->file_stream.get(),
222 info_ptr->file_path), 208 info_ptr->file_path),
223 base::Bind(&DriveUploader::OpenCompletionCallback, 209 base::Bind(&DriveUploader::OpenCompletionCallback,
224 weak_ptr_factory_.GetWeakPtr(), 210 weak_ptr_factory_.GetWeakPtr(),
225 base::Passed(&upload_file_info))); 211 base::Passed(&upload_file_info),
212 start_initiate_upload_callback));
226 } 213 }
227 214
228 void DriveUploader::OpenCompletionCallback( 215 void DriveUploader::OpenCompletionCallback(
229 scoped_ptr<UploadFileInfo> upload_file_info, int64 file_size) { 216 scoped_ptr<UploadFileInfo> upload_file_info,
217 const StartInitiateUploadCallback& start_initiate_upload_callback,
218 int64 file_size) {
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
231 220
232 if (file_size < 0) { 221 if (file_size < 0) {
233 UploadFailed(upload_file_info.Pass(), DRIVE_UPLOAD_ERROR_NOT_FOUND); 222 UploadFailed(upload_file_info.Pass(), DRIVE_UPLOAD_ERROR_NOT_FOUND);
234 return; 223 return;
235 } 224 }
236 225
237 upload_file_info->content_length = file_size; 226 upload_file_info->content_length = file_size;
238 227
239 // Open succeeded, initiate the upload. 228 // Open succeeded, initiate the upload.
229 start_initiate_upload_callback.Run(upload_file_info.Pass());
230 }
231
232 void DriveUploader::StartInitiateUploadNewFile(
233 const GURL& parent_upload_url,
234 const std::string& title,
235 scoped_ptr<UploadFileInfo> upload_file_info) {
236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
237
240 UploadFileInfo* info_ptr = upload_file_info.get(); 238 UploadFileInfo* info_ptr = upload_file_info.get();
241 drive_service_->InitiateUpload( 239 drive_service_->InitiateUploadNewFile(
242 InitiateUploadParams(info_ptr->upload_mode, 240 info_ptr->drive_path,
243 info_ptr->title, 241 info_ptr->content_type,
244 info_ptr->content_type, 242 info_ptr->content_length,
245 info_ptr->content_length, 243 parent_upload_url,
246 info_ptr->initial_upload_location, 244 title,
247 info_ptr->drive_path,
248 info_ptr->etag),
249 base::Bind(&DriveUploader::OnUploadLocationReceived, 245 base::Bind(&DriveUploader::OnUploadLocationReceived,
250 weak_ptr_factory_.GetWeakPtr(), 246 weak_ptr_factory_.GetWeakPtr(),
251 base::Passed(&upload_file_info))); 247 base::Passed(&upload_file_info)));
248 }
249
250 void DriveUploader::StartInitiateUploadExistingFile(
251 const GURL& upload_url,
252 const std::string& etag,
253 scoped_ptr<UploadFileInfo> upload_file_info) {
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
255
256 UploadFileInfo* info_ptr = upload_file_info.get();
257 drive_service_->InitiateUploadExistingFile(
258 info_ptr->drive_path,
259 info_ptr->content_type,
260 info_ptr->content_length,
261 upload_url,
262 etag,
263 base::Bind(&DriveUploader::OnUploadLocationReceived,
264 weak_ptr_factory_.GetWeakPtr(),
265 base::Passed(&upload_file_info)));
252 } 266 }
253 267
254 void DriveUploader::OnUploadLocationReceived( 268 void DriveUploader::OnUploadLocationReceived(
255 scoped_ptr<UploadFileInfo> upload_file_info, 269 scoped_ptr<UploadFileInfo> upload_file_info,
256 GDataErrorCode code, 270 GDataErrorCode code,
257 const GURL& upload_location) { 271 const GURL& upload_location) {
258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
259 273
260 DVLOG(1) << "Got upload location [" << upload_location.spec() 274 DVLOG(1) << "Got upload location [" << upload_location.spec()
261 << "] for [" << upload_file_info->title << "]"; 275 << "] for [" << upload_file_info->drive_path.value() << "]";
262 276
263 if (code != HTTP_SUCCESS) { 277 if (code != HTTP_SUCCESS) {
264 // TODO(achuith): Handle error codes from Google Docs server. 278 // TODO(achuith): Handle error codes from Google Docs server.
265 if (code == HTTP_PRECONDITION) { 279 if (code == HTTP_PRECONDITION) {
266 // ETag mismatch. 280 // ETag mismatch.
267 UploadFailed(upload_file_info.Pass(), DRIVE_UPLOAD_ERROR_CONFLICT); 281 UploadFailed(upload_file_info.Pass(), DRIVE_UPLOAD_ERROR_CONFLICT);
268 return; 282 return;
269 } 283 }
270 UploadFailed(upload_file_info.Pass(), DRIVE_UPLOAD_ERROR_ABORT); 284 UploadFailed(upload_file_info.Pass(), DRIVE_UPLOAD_ERROR_ABORT);
271 return; 285 return;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 void DriveUploader::OnUploadRangeResponseReceived( 365 void DriveUploader::OnUploadRangeResponseReceived(
352 scoped_ptr<UploadFileInfo> upload_file_info, 366 scoped_ptr<UploadFileInfo> upload_file_info,
353 const UploadRangeResponse& response, 367 const UploadRangeResponse& response,
354 scoped_ptr<ResourceEntry> entry) { 368 scoped_ptr<ResourceEntry> entry) {
355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
356 370
357 const UploadMode upload_mode = upload_file_info->upload_mode; 371 const UploadMode upload_mode = upload_file_info->upload_mode;
358 if ((upload_mode == UPLOAD_NEW_FILE && response.code == HTTP_CREATED) || 372 if ((upload_mode == UPLOAD_NEW_FILE && response.code == HTTP_CREATED) ||
359 (upload_mode == UPLOAD_EXISTING_FILE && response.code == HTTP_SUCCESS)) { 373 (upload_mode == UPLOAD_EXISTING_FILE && response.code == HTTP_SUCCESS)) {
360 DVLOG(1) << "Successfully created uploaded file=[" 374 DVLOG(1) << "Successfully created uploaded file=["
361 << upload_file_info->title << "]"; 375 << upload_file_info->drive_path.value() << "]";
362 376
363 // Done uploading. 377 // Done uploading.
364 upload_file_info->completion_callback.Run(DRIVE_UPLOAD_OK, 378 upload_file_info->completion_callback.Run(DRIVE_UPLOAD_OK,
365 upload_file_info->drive_path, 379 upload_file_info->drive_path,
366 upload_file_info->file_path, 380 upload_file_info->file_path,
367 entry.Pass()); 381 entry.Pass());
368 return; 382 return;
369 } 383 }
370 384
371 // ETag mismatch. 385 // ETag mismatch.
(...skipping 16 matching lines...) Expand all
388 << ", end_position_received=" << response.end_position_received 402 << ", end_position_received=" << response.end_position_received
389 << ", expected end range=" << upload_file_info->next_send_position; 403 << ", expected end range=" << upload_file_info->next_send_position;
390 UploadFailed(upload_file_info.Pass(), 404 UploadFailed(upload_file_info.Pass(),
391 response.code == HTTP_FORBIDDEN ? 405 response.code == HTTP_FORBIDDEN ?
392 DRIVE_UPLOAD_ERROR_NO_SPACE : DRIVE_UPLOAD_ERROR_ABORT); 406 DRIVE_UPLOAD_ERROR_NO_SPACE : DRIVE_UPLOAD_ERROR_ABORT);
393 return; 407 return;
394 } 408 }
395 409
396 DVLOG(1) << "Received range " << response.start_position_received 410 DVLOG(1) << "Received range " << response.start_position_received
397 << "-" << response.end_position_received 411 << "-" << response.end_position_received
398 << " for [" << upload_file_info->title << "]"; 412 << " for [" << upload_file_info->drive_path.value() << "]";
399 413
400 // Continue uploading. 414 // Continue uploading.
401 UploadNextChunk(upload_file_info.Pass()); 415 UploadNextChunk(upload_file_info.Pass());
402 } 416 }
403 417
404 void DriveUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info, 418 void DriveUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info,
405 DriveUploadError error) { 419 DriveUploadError error) {
406 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
407 421
408 LOG(ERROR) << "Upload failed " << upload_file_info->DebugString(); 422 LOG(ERROR) << "Upload failed " << upload_file_info->DebugString();
409 423
410 upload_file_info->completion_callback.Run(error, 424 upload_file_info->completion_callback.Run(error,
411 upload_file_info->drive_path, 425 upload_file_info->drive_path,
412 upload_file_info->file_path, 426 upload_file_info->file_path,
413 scoped_ptr<ResourceEntry>()); 427 scoped_ptr<ResourceEntry>());
414 } 428 }
415 429
416 } // namespace google_apis 430 } // namespace google_apis
OLDNEW
« no previous file with comments | « chrome/browser/google_apis/drive_uploader.h ('k') | chrome/browser/google_apis/drive_uploader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698