summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/gdata/gdata_uploader.h
blob: 3d853ff30291a39bebd32a23d54d79c0992a7d3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_CHROMEOS_GDATA_GDATA_UPLOADER_H_
#define CHROME_BROWSER_CHROMEOS_GDATA_GDATA_UPLOADER_H_

#include <map>
#include <set>
#include <string>

#include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
#include "base/platform_file.h"
#include "chrome/browser/chromeos/gdata/gdata_errorcode.h"
#include "chrome/browser/chromeos/gdata/gdata_operations.h"
#include "chrome/browser/chromeos/gdata/gdata_upload_file_info.h"
#include "googleurl/src/gurl.h"

namespace content {
class DownloadItem;
}

namespace gdata {

class DriveServiceInterface;

class GDataUploaderInterface {
 public:
  virtual ~GDataUploaderInterface() {}

  // Uploads a new file specified by |upload_file_info|. Transfers ownership.
  // Returns the upload_id.
  //
  // WARNING: This is not mockable by gmock because it takes scoped_ptr<>.
  // See "Announcing scoped_ptr<>::Pass(). The latest in pointer ownership
  // technology!" thread on chromium-dev.
  virtual int UploadNewFile(scoped_ptr<UploadFileInfo> upload_file_info) = 0;

  // Stream data to an existing file from data specified by |upload_file_info|.
  // Transfers ownership. Returns the upload_id.
  // TODO(zork): Do not use UploadFileInfo to pass data.  See: crbug.com/134819
  virtual int StreamExistingFile(
      scoped_ptr<UploadFileInfo> upload_file_info) = 0;

  // Uploads an existing file (a file that already exists on Drive)
  // specified by |local_file_path|. The existing file on Drive will be
  // updated. Returns the upload_id. |callback| is run upon completion or
  // failure.
  virtual int UploadExistingFile(
      const GURL& upload_location,
      const FilePath& gdata_file_path,
      const FilePath& local_file_path,
      int64 file_size,
      const std::string& content_type,
      const UploadFileInfo::UploadCompletionCallback& callback) = 0;

  // Updates attributes of streaming upload.
  virtual void UpdateUpload(int upload_id,
                            content::DownloadItem* download) = 0;

  // Returns the count of bytes confirmed as uploaded so far.
  virtual int64 GetUploadedBytes(int upload_id) const = 0;
};

class GDataUploader : public GDataUploaderInterface {
 public:
  explicit GDataUploader(DriveServiceInterface* drive_service);
  virtual ~GDataUploader();

  // GDataUploaderInterface overrides.
  virtual int UploadNewFile(
      scoped_ptr<UploadFileInfo> upload_file_info) OVERRIDE;
  virtual int StreamExistingFile(
      scoped_ptr<UploadFileInfo> upload_file_info) OVERRIDE;
  virtual int UploadExistingFile(
      const GURL& upload_location,
      const FilePath& gdata_file_path,
      const FilePath& local_file_path,
      int64 file_size,
      const std::string& content_type,
      const UploadFileInfo::UploadCompletionCallback& callback) OVERRIDE;
  virtual void UpdateUpload(
      int upload_id, content::DownloadItem* download) OVERRIDE;
  virtual int64 GetUploadedBytes(int upload_id) const OVERRIDE;

 private:
  // Lookup UploadFileInfo* in pending_uploads_.
  UploadFileInfo* GetUploadFileInfo(int upload_id) const;

  // Open the file.
  void OpenFile(UploadFileInfo* upload_file_info);

  // net::FileStream::Open completion callback. The result of the file
  // open operation is passed as |result|.
  void OpenCompletionCallback(int upload_id, int result);

  // DriveService callback for InitiateUpload.
  void OnUploadLocationReceived(int upload_id,
                                GDataErrorCode code,
                                const GURL& upload_location);

  // Uploads the next chunk of data from the file.
  void UploadNextChunk(UploadFileInfo* upload_file_info);

  // net::FileStream::Read completion callback.
  void ReadCompletionCallback(int upload_id,
      int bytes_to_read,
      int bytes_read);

  // Calls DriveService's ResumeUpload with the current upload info.
  void ResumeUpload(int upload_id);

  // DriveService callback for ResumeUpload.
  void OnResumeUploadResponseReceived(int upload_id,
                                      const ResumeUploadResponse& response,
                                      scoped_ptr<DocumentEntry> entry);

  // Initiate the upload.
  void InitiateUpload(UploadFileInfo* uploader_file_info);

  // Handle failed uploads.
  void UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info,
                    DriveFileError error);

  // Removes |upload_id| from UploadFileInfoMap |pending_uploads_|.
  // Note that this does not delete the UploadFileInfo object itself,
  // because it may still be in use by an asynchronous function.
  void RemoveUpload(int upload_id);

  // Starts uploading a file with |upload_file_info|. Returns a new upload
  // ID assigned to |upload_file_info|.
  int StartUploadFile(scoped_ptr<UploadFileInfo> upload_file_info);

  // Pointers to DriveServiceInterface object owned by DriveSystemService.
  // The lifetime of this object is guaranteed to exceed that of the
  // GDataUploader instance.
  DriveServiceInterface* drive_service_;

  int next_upload_id_;  // id counter.

  typedef std::map<int, UploadFileInfo*> UploadFileInfoMap;
  UploadFileInfoMap pending_uploads_;

  // Note: This should remain the last member so it'll be destroyed and
  // invalidate its weak pointers before any other members are destroyed.
  base::WeakPtrFactory<GDataUploader> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(GDataUploader);
};

}  // namespace gdata

#endif  // CHROME_BROWSER_CHROMEOS_GDATA_GDATA_UPLOADER_H_