drive_uploader.cc revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/drive_uploader.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 11a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/file_util.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 13a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/task_runner_util.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/drive_service_interface.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/google_apis/gdata_wapi_parser.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/power_save_blocker.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback; 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_CANCELLED; 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDataErrorCode; 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_NO_SPACE; 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CONFLICT; 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CREATED; 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_FORBIDDEN; 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_NOT_FOUND; 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_PRECONDITION; 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_RESUME_INCOMPLETE; 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS; 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback; 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceEntry; 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse; 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace { 3858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// Upload data is split to multiple HTTP request each conveying kUploadChunkSize 3958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// bytes (except the request for uploading the last chunk of data). 4058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// The value must be a multiple of 512KB according to the spec of GData WAPI and 4158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// Drive API v2. It is set to a smaller value than 2^31 for working around 4258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// server side error (crbug.com/264089). 4358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochconst int64 kUploadChunkSize = (1LL << 30); // 1GB 4458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch} // namespace 4558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Structure containing current upload information of file, passed between 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DriveServiceInterface methods and callbacks. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct DriveUploader::UploadFileInfo { 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UploadFileInfo(const base::FilePath& local_path, 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const UploadCompletionCallback& callback, 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : file_path(local_path), 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_type(content_type), 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_callback(callback), 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) progress_callback(progress_callback), 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_length(0), 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) power_save_blocker(content::PowerSaveBlocker::Create( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "Upload in progress")), 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cancelled(false), 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) weak_ptr_factory_(this) { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~UploadFileInfo() { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Useful for printf debugging. 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string DebugString() const { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "file_path=[" + file_path.AsUTF8Unsafe() + 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "], content_type=[" + content_type + 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "], content_length=[" + base::UintToString(content_length) + 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "]"; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Returns the callback to cancel the upload represented by this struct. 777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CancelCallback GetCancelCallback() { 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return base::Bind(&UploadFileInfo::Cancel, weak_ptr_factory_.GetWeakPtr()); 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The local file path of the file to be uploaded. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath file_path; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Content-Type of file. 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string content_type; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Callback to be invoked once the upload has finished. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const UploadCompletionCallback completion_callback; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Callback to periodically notify the upload progress. 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback progress_callback; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Location URL where file is to be uploaded to, returned from 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // InitiateUpload. Used for the subsequent ResumeUpload requests. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL upload_location; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Header content-Length. 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Blocks system suspend while upload is in progress. 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<content::PowerSaveBlocker> power_save_blocker; 1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Fields for implementing cancellation. |cancel_callback| is non-null if 1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // there is an in-flight HTTP request. In that case, |cancell_callback| will 1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // cancel the operation. |cancelled| is initially false and turns to true 1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // once Cancel() is called. DriveUploader will check this field before after 1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // an async task other than HTTP requests and cancels the subsequent requests 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // if this is flagged to true. 1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CancelCallback cancel_callback; 1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool cancelled; 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private: 1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Cancels the upload represented by this struct. 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void Cancel() { 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cancelled = true; 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!cancel_callback.is_null()) 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) cancel_callback.Run(); 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::WeakPtrFactory<UploadFileInfo> weak_ptr_factory_; 1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UploadFileInfo); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochDriveUploader::DriveUploader(DriveServiceInterface* drive_service, 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::TaskRunner* blocking_task_runner) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : drive_service_(drive_service), 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blocking_task_runner_(blocking_task_runner), 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveUploader::~DriveUploader() {} 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::UploadNewFile( 1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& parent_resource_id, 1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::FilePath& local_file_path, 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& title, 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& content_type, 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const UploadCompletionCallback& callback, 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const ProgressCallback& progress_callback) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!parent_resource_id.empty()); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!local_file_path.empty()); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!title.empty()); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!content_type.empty()); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return StartUploadFile( 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<UploadFileInfo>(new UploadFileInfo(local_file_path, 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_type, 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) progress_callback)), 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::StartInitiateUploadNewFile, 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_resource_id, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) title)); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::UploadExistingFile( 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& local_file_path, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const UploadCompletionCallback& callback, 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!resource_id.empty()); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!local_file_path.empty()); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!content_type.empty()); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return StartUploadFile( 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<UploadFileInfo>(new UploadFileInfo(local_file_path, 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_type, 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback, 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) progress_callback)), 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::StartInitiateUploadExistingFile, 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) etag)); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::ResumeUploadFile( 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GURL& upload_location, 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::FilePath& local_file_path, 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& content_type, 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const UploadCompletionCallback& callback, 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ProgressCallback& progress_callback) { 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!local_file_path.empty()); 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!content_type.empty()); 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!callback.is_null()); 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo( 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch local_file_path, content_type, 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback, progress_callback)); 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) upload_file_info->upload_location = upload_location; 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return StartUploadFile( 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) upload_file_info.Pass(), 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&DriveUploader::StartGetUploadStatus, 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::StartUploadFile( 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info, 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StartInitiateUploadCallback& start_initiate_upload_callback) { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Uploading file: " << upload_file_info->DebugString(); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PostTaskAndReplyWithResult( 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blocking_task_runner_.get(), 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&file_util::GetFileSize, 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch info_ptr->file_path, 216a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &info_ptr->content_length), 217a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Bind(&DriveUploader::StartUploadFileAfterGetFileSize, 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&upload_file_info), 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_initiate_upload_callback)); 2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return info_ptr->GetCancelCallback(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 224a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void DriveUploader::StartUploadFileAfterGetFileSize( 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info, 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StartInitiateUploadCallback& start_initiate_upload_callback, 227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) bool get_file_size_result) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!get_file_size_result) { 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UploadFailed(upload_file_info.Pass(), HTTP_NOT_FOUND); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK_GE(upload_file_info->content_length, 0); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (upload_file_info->cancelled) { 2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) UploadFailed(upload_file_info.Pass(), GDATA_CANCELLED); 2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_initiate_upload_callback.Run(upload_file_info.Pass()); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::StartInitiateUploadNewFile( 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& parent_resource_id, 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& title, 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info) { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info_ptr->cancel_callback = drive_service_->InitiateUploadNewFile( 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_type, 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_length, 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent_resource_id, 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) title, 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadLocationReceived, 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&upload_file_info))); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::StartInitiateUploadExistingFile( 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& resource_id, 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& etag, 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info_ptr->cancel_callback = drive_service_->InitiateUploadExistingFile( 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_type, 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_length, 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_id, 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) etag, 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadLocationReceived, 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&upload_file_info))); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::OnUploadLocationReceived( 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info, 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDataErrorCode code, 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_location) { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Got upload location [" << upload_location.spec() 284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "] for [" << upload_file_info->file_path.value() << "]"; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (code != HTTP_SUCCESS) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(achuith): Handle error codes from Google Docs server. 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (code == HTTP_PRECONDITION) { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ETag mismatch. 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UploadFailed(upload_file_info.Pass(), HTTP_CONFLICT); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UploadFailed(upload_file_info.Pass(), code); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) upload_file_info->upload_location = upload_location; 2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) UploadNextChunk(upload_file_info.Pass(), 0); // start_position 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DriveUploader::StartGetUploadStatus( 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info) { 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(upload_file_info); 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info_ptr->cancel_callback = drive_service_->GetUploadStatus( 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) info_ptr->upload_location, 30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) info_ptr->content_length, 31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadRangeResponseReceived, 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Passed(&upload_file_info))); 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 315a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void DriveUploader::UploadNextChunk( 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info, 317a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int64 start_position) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 319a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(upload_file_info); 320a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK_GE(start_position, 0); 321a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK_LE(start_position, upload_file_info->content_length); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (upload_file_info->cancelled) { 3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) UploadFailed(upload_file_info.Pass(), GDATA_CANCELLED); 3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 32858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // Limit the size of data uploaded per each request by kUploadChunkSize. 32958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch const int64 end_position = std::min(upload_file_info->content_length, 33058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch start_position + kUploadChunkSize); 33158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadFileInfo* info_ptr = upload_file_info.get(); 3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) info_ptr->cancel_callback = drive_service_->ResumeUpload( 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->upload_location, 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_position, 33658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch end_position, 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_length, 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info_ptr->content_type, 339a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) info_ptr->file_path, 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadRangeResponseReceived, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&upload_file_info)), 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&DriveUploader::OnUploadProgress, 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_ptr->progress_callback, 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) start_position, 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info_ptr->content_length)); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::OnUploadRangeResponseReceived( 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<UploadFileInfo> upload_file_info, 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const UploadRangeResponse& response, 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ResourceEntry> entry) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (response.code == HTTP_CREATED || response.code == HTTP_SUCCESS) { 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // When uploading a new file, we expect HTTP_CREATED, and when uploading 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // an existing file (to overwrite), we expect HTTP_SUCCESS. 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // There is an exception: if we uploading an empty file, uploading a new 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // file also returns HTTP_SUCCESS on Drive API v2. The correct way of the 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // fix should be uploading the metadata only. However, to keep the 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // compatibility with GData WAPI during the migration period, we just 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // relax the condition here. 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(hidehiko): Upload metadata only for empty files, after GData WAPI 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // code is gone. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Successfully created uploaded file=[" 367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << upload_file_info->file_path.value() << "]"; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Done uploading. 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) upload_file_info->completion_callback.Run( 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HTTP_SUCCESS, GURL(), entry.Pass()); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ETag mismatch. 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (response.code == HTTP_PRECONDITION) { 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UploadFailed(upload_file_info.Pass(), HTTP_CONFLICT); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 381a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // If code is 308 (RESUME_INCOMPLETE) and |range_received| starts with 0 382a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // (meaning that the data is uploaded from the beginning of the file), 383a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // proceed to upload the next chunk. 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response.code != HTTP_RESUME_INCOMPLETE || 385a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) response.start_position_received != 0) { 386a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) LOG(ERROR) 387a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) << "UploadNextChunk http code=" << response.code 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ", start_position_received=" << response.start_position_received 389a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) << ", end_position_received=" << response.end_position_received; 390a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) UploadFailed( 391a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) upload_file_info.Pass(), 392a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) response.code == HTTP_FORBIDDEN ? GDATA_NO_SPACE : response.code); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Received range " << response.start_position_received 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "-" << response.end_position_received 398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << " for [" << upload_file_info->file_path.value() << "]"; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) UploadNextChunk(upload_file_info.Pass(), response.end_position_received); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DriveUploader::OnUploadProgress(const ProgressCallback& callback, 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 start_position, 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 total_size, 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 progress_of_chunk, 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 total_of_chunk) { 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!callback.is_null()) 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(start_position + progress_of_chunk, total_size); 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info, 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GDataErrorCode error) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Upload failed " << upload_file_info->DebugString(); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) upload_file_info->completion_callback.Run( 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error, upload_file_info->upload_location, scoped_ptr<ResourceEntry>()); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace drive 423