drive_uploader.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Structure containing current upload information of file, passed between
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DriveServiceInterface methods and callbacks.
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct DriveUploader::UploadFileInfo {
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  UploadFileInfo(const base::FilePath& local_path,
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 const std::string& content_type,
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 const UploadCompletionCallback& callback,
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 const ProgressCallback& progress_callback)
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : file_path(local_path),
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content_type(content_type),
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        completion_callback(callback),
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        progress_callback(progress_callback),
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content_length(0),
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        power_save_blocker(content::PowerSaveBlocker::Create(
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            "Upload in progress")),
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        cancelled(false),
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        weak_ptr_factory_(this) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~UploadFileInfo() {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Useful for printf debugging.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string DebugString() const {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return "file_path=[" + file_path.AsUTF8Unsafe() +
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           "], content_type=[" + content_type +
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           "], content_length=[" + base::UintToString(content_length) +
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           "]";
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the callback to cancel the upload represented by this struct.
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CancelCallback GetCancelCallback() {
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return base::Bind(&UploadFileInfo::Cancel, weak_ptr_factory_.GetWeakPtr());
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The local file path of the file to be uploaded.
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath file_path;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Content-Type of file.
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string content_type;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callback to be invoked once the upload has finished.
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const UploadCompletionCallback completion_callback;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Callback to periodically notify the upload progress.
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const ProgressCallback progress_callback;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Location URL where file is to be uploaded to, returned from
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // InitiateUpload. Used for the subsequent ResumeUpload requests.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL upload_location;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Header content-Length.
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 content_length;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Blocks system suspend while upload is in progress.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<content::PowerSaveBlocker> power_save_blocker;
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Fields for implementing cancellation. |cancel_callback| is non-null if
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // there is an in-flight HTTP request. In that case, |cancell_callback| will
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // cancel the operation. |cancelled| is initially false and turns to true
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // once Cancel() is called. DriveUploader will check this field before after
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // an async task other than HTTP requests and cancels the subsequent requests
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // if this is flagged to true.
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CancelCallback cancel_callback;
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool cancelled;
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Cancels the upload represented by this struct.
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void Cancel() {
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    cancelled = true;
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!cancel_callback.is_null())
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      cancel_callback.Run();
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::WeakPtrFactory<UploadFileInfo> weak_ptr_factory_;
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UploadFileInfo);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochDriveUploader::DriveUploader(DriveServiceInterface* drive_service,
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             base::TaskRunner* blocking_task_runner)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : drive_service_(drive_service),
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      blocking_task_runner_(blocking_task_runner),
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_ptr_factory_(this) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveUploader::~DriveUploader() {}
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::UploadNewFile(
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& parent_resource_id,
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const base::FilePath& local_file_path,
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& title,
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& content_type,
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const UploadCompletionCallback& callback,
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const ProgressCallback& progress_callback) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!parent_resource_id.empty());
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!local_file_path.empty());
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!title.empty());
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!content_type.empty());
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return StartUploadFile(
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      scoped_ptr<UploadFileInfo>(new UploadFileInfo(local_file_path,
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                    content_type,
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                    callback,
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                    progress_callback)),
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DriveUploader::StartInitiateUploadNewFile,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 parent_resource_id,
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 title));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::UploadExistingFile(
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& local_file_path,
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UploadCompletionCallback& callback,
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_callback) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!resource_id.empty());
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!local_file_path.empty());
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!content_type.empty());
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return StartUploadFile(
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      scoped_ptr<UploadFileInfo>(new UploadFileInfo(local_file_path,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                    content_type,
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                    callback,
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                    progress_callback)),
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DriveUploader::StartInitiateUploadExistingFile,
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 resource_id,
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 etag));
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::ResumeUploadFile(
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const GURL& upload_location,
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::FilePath& local_file_path,
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& content_type,
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const UploadCompletionCallback& callback,
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const ProgressCallback& progress_callback) {
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!local_file_path.empty());
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!content_type.empty());
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!callback.is_null());
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo(
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      local_file_path, content_type,
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      callback, progress_callback));
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  upload_file_info->upload_location = upload_location;
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return StartUploadFile(
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      upload_file_info.Pass(),
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&DriveUploader::StartGetUploadStatus,
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveUploader::StartUploadFile(
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<UploadFileInfo> upload_file_info,
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StartInitiateUploadCallback& start_initiate_upload_callback) {
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Uploading file: " << upload_file_info->DebugString();
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadFileInfo* info_ptr = upload_file_info.get();
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::PostTaskAndReplyWithResult(
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      blocking_task_runner_.get(),
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&file_util::GetFileSize,
206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 info_ptr->file_path,
207a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                 &info_ptr->content_length),
208a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::Bind(&DriveUploader::StartUploadFileAfterGetFileSize,
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Passed(&upload_file_info),
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 start_initiate_upload_callback));
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return info_ptr->GetCancelCallback();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void DriveUploader::StartUploadFileAfterGetFileSize(
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<UploadFileInfo> upload_file_info,
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StartInitiateUploadCallback& start_initiate_upload_callback,
218a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    bool get_file_size_result) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
221a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!get_file_size_result) {
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UploadFailed(upload_file_info.Pass(), HTTP_NOT_FOUND);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
225a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK_GE(upload_file_info->content_length, 0);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (upload_file_info->cancelled) {
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UploadFailed(upload_file_info.Pass(), GDATA_CANCELLED);
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  start_initiate_upload_callback.Run(upload_file_info.Pass());
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::StartInitiateUploadNewFile(
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& title,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<UploadFileInfo> upload_file_info) {
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadFileInfo* info_ptr = upload_file_info.get();
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  info_ptr->cancel_callback = drive_service_->InitiateUploadNewFile(
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info_ptr->content_type,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info_ptr->content_length,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      parent_resource_id,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      title,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DriveUploader::OnUploadLocationReceived,
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Passed(&upload_file_info)));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::StartInitiateUploadExistingFile(
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<UploadFileInfo> upload_file_info) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadFileInfo* info_ptr = upload_file_info.get();
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  info_ptr->cancel_callback = drive_service_->InitiateUploadExistingFile(
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info_ptr->content_type,
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info_ptr->content_length,
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id,
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      etag,
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DriveUploader::OnUploadLocationReceived,
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Passed(&upload_file_info)));
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::OnUploadLocationReceived(
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<UploadFileInfo> upload_file_info,
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GDataErrorCode code,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_location) {
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Got upload location [" << upload_location.spec()
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           << "] for [" << upload_file_info->file_path.value() << "]";
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (code != HTTP_SUCCESS) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(achuith): Handle error codes from Google Docs server.
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (code == HTTP_PRECONDITION) {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // ETag mismatch.
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UploadFailed(upload_file_info.Pass(), HTTP_CONFLICT);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UploadFailed(upload_file_info.Pass(), code);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  upload_file_info->upload_location = upload_location;
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UploadNextChunk(upload_file_info.Pass(), 0);  // start_position
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DriveUploader::StartGetUploadStatus(
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_ptr<UploadFileInfo> upload_file_info) {
29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(upload_file_info);
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UploadFileInfo* info_ptr = upload_file_info.get();
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  info_ptr->cancel_callback = drive_service_->GetUploadStatus(
29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      info_ptr->upload_location,
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      info_ptr->content_length,
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&DriveUploader::OnUploadRangeResponseReceived,
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 base::Passed(&upload_file_info)));
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
306a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void DriveUploader::UploadNextChunk(
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<UploadFileInfo> upload_file_info,
308a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    int64 start_position) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
310a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(upload_file_info);
311a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK_GE(start_position, 0);
312a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK_LE(start_position, upload_file_info->content_length);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (upload_file_info->cancelled) {
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UploadFailed(upload_file_info.Pass(), GDATA_CANCELLED);
3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadFileInfo* info_ptr = upload_file_info.get();
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  info_ptr->cancel_callback = drive_service_->ResumeUpload(
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info_ptr->upload_location,
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      start_position,
323a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      info_ptr->content_length,
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info_ptr->content_length,
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      info_ptr->content_type,
326a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      info_ptr->file_path,
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DriveUploader::OnUploadRangeResponseReceived,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Passed(&upload_file_info)),
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&DriveUploader::OnUploadProgress,
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 info_ptr->progress_callback,
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 start_position,
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 info_ptr->content_length));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::OnUploadRangeResponseReceived(
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<UploadFileInfo> upload_file_info,
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeResponse& response,
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ResourceEntry> entry) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (response.code == HTTP_CREATED || response.code == HTTP_SUCCESS) {
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // When uploading a new file, we expect HTTP_CREATED, and when uploading
34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // an existing file (to overwrite), we expect HTTP_SUCCESS.
34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // There is an exception: if we uploading an empty file, uploading a new
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // file also returns HTTP_SUCCESS on Drive API v2. The correct way of the
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // fix should be uploading the metadata only. However, to keep the
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // compatibility with GData WAPI during the migration period, we just
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // relax the condition here.
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // TODO(hidehiko): Upload metadata only for empty files, after GData WAPI
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // code is gone.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Successfully created uploaded file=["
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             << upload_file_info->file_path.value() << "]";
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Done uploading.
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    upload_file_info->completion_callback.Run(
35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        HTTP_SUCCESS, GURL(), entry.Pass());
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ETag mismatch.
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (response.code == HTTP_PRECONDITION) {
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UploadFailed(upload_file_info.Pass(), HTTP_CONFLICT);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
368a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // If code is 308 (RESUME_INCOMPLETE) and |range_received| starts with 0
369a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // (meaning that the data is uploaded from the beginning of the file),
370a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // proceed to upload the next chunk.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response.code != HTTP_RESUME_INCOMPLETE ||
372a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      response.start_position_received != 0) {
373a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    LOG(ERROR)
374a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        << "UploadNextChunk http code=" << response.code
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << ", start_position_received=" << response.start_position_received
376a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        << ", end_position_received=" << response.end_position_received;
377a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    UploadFailed(
378a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        upload_file_info.Pass(),
379a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        response.code == HTTP_FORBIDDEN ? GDATA_NO_SPACE : response.code);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Received range " << response.start_position_received
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << "-" << response.end_position_received
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           << " for [" << upload_file_info->file_path.value() << "]";
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UploadNextChunk(upload_file_info.Pass(), response.end_position_received);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DriveUploader::OnUploadProgress(const ProgressCallback& callback,
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     int64 start_position,
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     int64 total_size,
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     int64 progress_of_chunk,
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     int64 total_of_chunk) {
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!callback.is_null())
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.Run(start_position + progress_of_chunk, total_size);
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info,
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 GDataErrorCode error) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(ERROR) << "Upload failed " << upload_file_info->DebugString();
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  upload_file_info->completion_callback.Run(
40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      error, upload_file_info->upload_location, scoped_ptr<ResourceEntry>());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive
410