| OLD | NEW |
| 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 Loading... |
| 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, | |
| 49 const FilePath& drive_path, | 48 const FilePath& drive_path, |
| 50 const FilePath& local_path, | 49 const 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 FilePath drive_path; | 90 const 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 FilePath file_path; | 93 const 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 Loading... |
| 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 FilePath& drive_file_path, | 141 const FilePath& drive_file_path, |
| 157 const FilePath& local_file_path, | 142 const 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 FilePath& drive_file_path, | 169 const FilePath& drive_file_path, |
| 185 const FilePath& local_file_path, | 170 const 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |