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/chromeos/gdata/gdata_uploader.h" | 5 #include "chrome/browser/chromeos/gdata/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" |
11 #include "chrome/browser/chromeos/gdata/drive_service_interface.h" | 11 #include "chrome/browser/chromeos/gdata/drive_service_interface.h" |
12 #include "chrome/browser/chromeos/gdata/gdata_upload_file_info.h" | 12 #include "chrome/browser/chromeos/gdata/drive_upload_file_info.h" |
13 #include "chrome/browser/chromeos/gdata/gdata_wapi_parser.h" | 13 #include "chrome/browser/chromeos/gdata/gdata_wapi_parser.h" |
14 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/browser/download_item.h" | 15 #include "content/public/browser/download_item.h" |
16 #include "net/base/file_stream.h" | 16 #include "net/base/file_stream.h" |
17 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
18 | 18 |
19 using content::BrowserThread; | 19 using content::BrowserThread; |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 // Google Documents List API requires uploading in chunks of 512kB. | 23 // Google Documents List API requires uploading in chunks of 512kB. |
24 const int64 kUploadChunkSize = 512 * 1024; | 24 const int64 kUploadChunkSize = 512 * 1024; |
25 | 25 |
26 // Maximum number of times we try to open a file before giving up. | 26 // Maximum number of times we try to open a file before giving up. |
27 const int kMaxFileOpenTries = 5; | 27 const int kMaxFileOpenTries = 5; |
28 | 28 |
29 } // namespace | 29 } // namespace |
30 | 30 |
31 namespace gdata { | 31 namespace gdata { |
32 | 32 |
33 GDataUploader::GDataUploader(DriveServiceInterface* drive_service) | 33 DriveUploader::DriveUploader(DriveServiceInterface* drive_service) |
34 : drive_service_(drive_service), | 34 : drive_service_(drive_service), |
35 next_upload_id_(0), | 35 next_upload_id_(0), |
36 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 36 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
37 } | 37 } |
38 | 38 |
39 GDataUploader::~GDataUploader() { | 39 DriveUploader::~DriveUploader() { |
40 } | 40 } |
41 | 41 |
42 int GDataUploader::UploadNewFile(scoped_ptr<UploadFileInfo> upload_file_info) { | 42 int DriveUploader::UploadNewFile(scoped_ptr<UploadFileInfo> upload_file_info) { |
43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
44 DCHECK(upload_file_info.get()); | 44 DCHECK(upload_file_info.get()); |
45 DCHECK_EQ(upload_file_info->upload_id, -1); | 45 DCHECK_EQ(upload_file_info->upload_id, -1); |
46 DCHECK(!upload_file_info->file_path.empty()); | 46 DCHECK(!upload_file_info->file_path.empty()); |
47 DCHECK(!upload_file_info->gdata_path.empty()); | 47 DCHECK(!upload_file_info->drive_path.empty()); |
48 DCHECK(!upload_file_info->title.empty()); | 48 DCHECK(!upload_file_info->title.empty()); |
49 DCHECK(!upload_file_info->content_type.empty()); | 49 DCHECK(!upload_file_info->content_type.empty()); |
50 DCHECK(!upload_file_info->initial_upload_location.is_empty()); | 50 DCHECK(!upload_file_info->initial_upload_location.is_empty()); |
51 DCHECK_EQ(UPLOAD_INVALID, upload_file_info->upload_mode); | 51 DCHECK_EQ(UPLOAD_INVALID, upload_file_info->upload_mode); |
52 | 52 |
53 upload_file_info->upload_mode = UPLOAD_NEW_FILE; | 53 upload_file_info->upload_mode = UPLOAD_NEW_FILE; |
54 | 54 |
55 // When uploading a new file, we should retry file open as the file may | 55 // When uploading a new file, we should retry file open as the file may |
56 // not yet be ready. See comments in OpenCompletionCallback. | 56 // not yet be ready. See comments in OpenCompletionCallback. |
57 // TODO(satorux): The retry should be done only when we are uploading | 57 // TODO(satorux): The retry should be done only when we are uploading |
58 // while downloading files from web sites (i.e. saving files to Drive). | 58 // while downloading files from web sites (i.e. saving files to Drive). |
59 upload_file_info->should_retry_file_open = true; | 59 upload_file_info->should_retry_file_open = true; |
60 return StartUploadFile(upload_file_info.Pass()); | 60 return StartUploadFile(upload_file_info.Pass()); |
61 } | 61 } |
62 | 62 |
63 int GDataUploader::StreamExistingFile( | 63 int DriveUploader::StreamExistingFile( |
64 scoped_ptr<UploadFileInfo> upload_file_info) { | 64 scoped_ptr<UploadFileInfo> upload_file_info) { |
65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
66 DCHECK(upload_file_info.get()); | 66 DCHECK(upload_file_info.get()); |
67 DCHECK_EQ(upload_file_info->upload_id, -1); | 67 DCHECK_EQ(upload_file_info->upload_id, -1); |
68 DCHECK(!upload_file_info->file_path.empty()); | 68 DCHECK(!upload_file_info->file_path.empty()); |
69 DCHECK(!upload_file_info->gdata_path.empty()); | 69 DCHECK(!upload_file_info->drive_path.empty()); |
70 DCHECK(upload_file_info->title.empty()); | 70 DCHECK(upload_file_info->title.empty()); |
71 DCHECK(!upload_file_info->content_type.empty()); | 71 DCHECK(!upload_file_info->content_type.empty()); |
72 DCHECK(!upload_file_info->initial_upload_location.is_empty()); | 72 DCHECK(!upload_file_info->initial_upload_location.is_empty()); |
73 DCHECK_EQ(UPLOAD_INVALID, upload_file_info->upload_mode); | 73 DCHECK_EQ(UPLOAD_INVALID, upload_file_info->upload_mode); |
74 | 74 |
75 upload_file_info->upload_mode = UPLOAD_EXISTING_FILE; | 75 upload_file_info->upload_mode = UPLOAD_EXISTING_FILE; |
76 | 76 |
77 // When uploading a new file, we should retry file open as the file may | 77 // When uploading a new file, we should retry file open as the file may |
78 // not yet be ready. See comments in OpenCompletionCallback. | 78 // not yet be ready. See comments in OpenCompletionCallback. |
79 // TODO(satorux): The retry should be done only when we are uploading | 79 // TODO(satorux): The retry should be done only when we are uploading |
80 // while downloading files from web sites (i.e. saving files to Drive). | 80 // while downloading files from web sites (i.e. saving files to Drive). |
81 upload_file_info->should_retry_file_open = true; | 81 upload_file_info->should_retry_file_open = true; |
82 return StartUploadFile(upload_file_info.Pass()); | 82 return StartUploadFile(upload_file_info.Pass()); |
83 } | 83 } |
84 | 84 |
85 int GDataUploader::StartUploadFile( | 85 int DriveUploader::StartUploadFile( |
86 scoped_ptr<UploadFileInfo> upload_file_info) { | 86 scoped_ptr<UploadFileInfo> upload_file_info) { |
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
88 DCHECK(upload_file_info.get()); | 88 DCHECK(upload_file_info.get()); |
89 DCHECK_EQ(upload_file_info->upload_id, -1); | 89 DCHECK_EQ(upload_file_info->upload_id, -1); |
90 DCHECK_NE(UPLOAD_INVALID, upload_file_info->upload_mode); | 90 DCHECK_NE(UPLOAD_INVALID, upload_file_info->upload_mode); |
91 | 91 |
92 const int upload_id = next_upload_id_++; | 92 const int upload_id = next_upload_id_++; |
93 upload_file_info->upload_id = upload_id; | 93 upload_file_info->upload_id = upload_id; |
94 | 94 |
95 // Add upload_file_info to our internal map and take ownership. | 95 // Add upload_file_info to our internal map and take ownership. |
96 pending_uploads_[upload_id] = upload_file_info.release(); | 96 pending_uploads_[upload_id] = upload_file_info.release(); |
97 | 97 |
98 UploadFileInfo* info = GetUploadFileInfo(upload_id); | 98 UploadFileInfo* info = GetUploadFileInfo(upload_id); |
99 DVLOG(1) << "Uploading file: " << info->DebugString(); | 99 DVLOG(1) << "Uploading file: " << info->DebugString(); |
100 | 100 |
101 // Create a FileStream to make sure the file can be opened successfully. | 101 // Create a FileStream to make sure the file can be opened successfully. |
102 info->file_stream = new net::FileStream(NULL); | 102 info->file_stream = new net::FileStream(NULL); |
103 | 103 |
104 // Create buffer to hold upload data. The full file size may not be known at | 104 // Create buffer to hold upload data. The full file size may not be known at |
105 // this point, so it may not be appropriate to use info->file_size. | 105 // this point, so it may not be appropriate to use info->file_size. |
106 info->buf_len = kUploadChunkSize; | 106 info->buf_len = kUploadChunkSize; |
107 info->buf = new net::IOBuffer(info->buf_len); | 107 info->buf = new net::IOBuffer(info->buf_len); |
108 | 108 |
109 OpenFile(info); | 109 OpenFile(info); |
110 return upload_id; | 110 return upload_id; |
111 } | 111 } |
112 | 112 |
113 int GDataUploader::UploadExistingFile( | 113 int DriveUploader::UploadExistingFile( |
114 const GURL& upload_location, | 114 const GURL& upload_location, |
115 const FilePath& gdata_file_path, | 115 const FilePath& drive_file_path, |
116 const FilePath& local_file_path, | 116 const FilePath& local_file_path, |
117 int64 file_size, | 117 int64 file_size, |
118 const std::string& content_type, | 118 const std::string& content_type, |
119 const UploadFileInfo::UploadCompletionCallback& callback) { | 119 const UploadFileInfo::UploadCompletionCallback& callback) { |
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
121 DCHECK(!upload_location.is_empty()); | 121 DCHECK(!upload_location.is_empty()); |
122 DCHECK(!local_file_path.empty()); | 122 DCHECK(!local_file_path.empty()); |
123 DCHECK(!content_type.empty()); | 123 DCHECK(!content_type.empty()); |
124 | 124 |
125 scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo); | 125 scoped_ptr<UploadFileInfo> upload_file_info(new UploadFileInfo); |
126 upload_file_info->upload_mode = UPLOAD_EXISTING_FILE; | 126 upload_file_info->upload_mode = UPLOAD_EXISTING_FILE; |
127 upload_file_info->initial_upload_location = upload_location; | 127 upload_file_info->initial_upload_location = upload_location; |
128 upload_file_info->file_path = local_file_path; | 128 upload_file_info->file_path = local_file_path; |
129 upload_file_info->file_size = file_size; | 129 upload_file_info->file_size = file_size; |
130 upload_file_info->content_type = content_type; | 130 upload_file_info->content_type = content_type; |
131 upload_file_info->completion_callback = callback; | 131 upload_file_info->completion_callback = callback; |
132 upload_file_info->gdata_path = gdata_file_path, | 132 upload_file_info->drive_path = drive_file_path, |
133 upload_file_info->content_length = file_size; | 133 upload_file_info->content_length = file_size; |
134 upload_file_info->all_bytes_present = true; | 134 upload_file_info->all_bytes_present = true; |
135 | 135 |
136 // When uploading an updated file, we should not retry file open as the | 136 // When uploading an updated file, we should not retry file open as the |
137 // file should already be present by definition. | 137 // file should already be present by definition. |
138 upload_file_info->should_retry_file_open = false; | 138 upload_file_info->should_retry_file_open = false; |
139 return StartUploadFile(upload_file_info.Pass()); | 139 return StartUploadFile(upload_file_info.Pass()); |
140 } | 140 } |
141 | 141 |
142 void GDataUploader::UpdateUpload(int upload_id, | 142 void DriveUploader::UpdateUpload(int upload_id, |
143 content::DownloadItem* download) { | 143 content::DownloadItem* download) { |
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
145 | 145 |
146 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); | 146 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); |
147 if (!upload_file_info) | 147 if (!upload_file_info) |
148 return; | 148 return; |
149 | 149 |
150 const int64 file_size = download->GetReceivedBytes(); | 150 const int64 file_size = download->GetReceivedBytes(); |
151 | 151 |
152 // Update file_size and all_bytes_present. | 152 // Update file_size and all_bytes_present. |
(...skipping 29 matching lines...) Expand all Loading... |
182 // rename on the FILE thread. Thus the new path is visible on the UI thread | 182 // rename on the FILE thread. Thus the new path is visible on the UI thread |
183 // before the renamed file is available on the file system. | 183 // before the renamed file is available on the file system. |
184 if (upload_file_info->should_retry_file_open) { | 184 if (upload_file_info->should_retry_file_open) { |
185 DCHECK(!download->IsComplete()); | 185 DCHECK(!download->IsComplete()); |
186 // Disallow further retries. | 186 // Disallow further retries. |
187 upload_file_info->should_retry_file_open = false; | 187 upload_file_info->should_retry_file_open = false; |
188 OpenFile(upload_file_info); | 188 OpenFile(upload_file_info); |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
192 int64 GDataUploader::GetUploadedBytes(int upload_id) const { | 192 int64 DriveUploader::GetUploadedBytes(int upload_id) const { |
193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
194 UploadFileInfo* upload_info = GetUploadFileInfo(upload_id); | 194 UploadFileInfo* upload_info = GetUploadFileInfo(upload_id); |
195 // We return the start_range as the count of uploaded bytes since that is the | 195 // We return the start_range as the count of uploaded bytes since that is the |
196 // start of the next or currently uploading chunk. | 196 // start of the next or currently uploading chunk. |
197 // TODO(asanka): Use a finer grained progress value than this. We end up | 197 // TODO(asanka): Use a finer grained progress value than this. We end up |
198 // reporting progress in kUploadChunkSize increments. | 198 // reporting progress in kUploadChunkSize increments. |
199 return upload_info ? upload_info->start_range : 0; | 199 return upload_info ? upload_info->start_range : 0; |
200 } | 200 } |
201 | 201 |
202 UploadFileInfo* GDataUploader::GetUploadFileInfo(int upload_id) const { | 202 UploadFileInfo* DriveUploader::GetUploadFileInfo(int upload_id) const { |
203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
204 | 204 |
205 UploadFileInfoMap::const_iterator it = pending_uploads_.find(upload_id); | 205 UploadFileInfoMap::const_iterator it = pending_uploads_.find(upload_id); |
206 DVLOG_IF(1, it == pending_uploads_.end()) << "No upload found for id " | 206 DVLOG_IF(1, it == pending_uploads_.end()) << "No upload found for id " |
207 << upload_id; | 207 << upload_id; |
208 return it != pending_uploads_.end() ? it->second : NULL; | 208 return it != pending_uploads_.end() ? it->second : NULL; |
209 } | 209 } |
210 | 210 |
211 void GDataUploader::OpenFile(UploadFileInfo* upload_file_info) { | 211 void DriveUploader::OpenFile(UploadFileInfo* upload_file_info) { |
212 // Open the file asynchronously. | 212 // Open the file asynchronously. |
213 const int rv = upload_file_info->file_stream->Open( | 213 const int rv = upload_file_info->file_stream->Open( |
214 upload_file_info->file_path, | 214 upload_file_info->file_path, |
215 base::PLATFORM_FILE_OPEN | | 215 base::PLATFORM_FILE_OPEN | |
216 base::PLATFORM_FILE_READ | | 216 base::PLATFORM_FILE_READ | |
217 base::PLATFORM_FILE_ASYNC, | 217 base::PLATFORM_FILE_ASYNC, |
218 base::Bind(&GDataUploader::OpenCompletionCallback, | 218 base::Bind(&DriveUploader::OpenCompletionCallback, |
219 weak_ptr_factory_.GetWeakPtr(), | 219 weak_ptr_factory_.GetWeakPtr(), |
220 upload_file_info->upload_id)); | 220 upload_file_info->upload_id)); |
221 DCHECK_EQ(net::ERR_IO_PENDING, rv); | 221 DCHECK_EQ(net::ERR_IO_PENDING, rv); |
222 } | 222 } |
223 | 223 |
224 void GDataUploader::OpenCompletionCallback(int upload_id, int result) { | 224 void DriveUploader::OpenCompletionCallback(int upload_id, int result) { |
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
226 | 226 |
227 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); | 227 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); |
228 if (!upload_file_info) | 228 if (!upload_file_info) |
229 return; | 229 return; |
230 | 230 |
231 // The file may actually not exist yet, as the downloads system downloads | 231 // The file may actually not exist yet, as the downloads system downloads |
232 // to a temp location and then renames the file. If this is the case, we | 232 // to a temp location and then renames the file. If this is the case, we |
233 // just retry opening the file later. | 233 // just retry opening the file later. |
234 if (result != net::OK) { | 234 if (result != net::OK) { |
(...skipping 25 matching lines...) Expand all Loading... |
260 UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info), | 260 UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info), |
261 DRIVE_FILE_ERROR_ABORT); | 261 DRIVE_FILE_ERROR_ABORT); |
262 return; | 262 return; |
263 } | 263 } |
264 drive_service_->InitiateUpload( | 264 drive_service_->InitiateUpload( |
265 InitiateUploadParams(upload_file_info->upload_mode, | 265 InitiateUploadParams(upload_file_info->upload_mode, |
266 upload_file_info->title, | 266 upload_file_info->title, |
267 upload_file_info->content_type, | 267 upload_file_info->content_type, |
268 upload_file_info->content_length, | 268 upload_file_info->content_length, |
269 upload_file_info->initial_upload_location, | 269 upload_file_info->initial_upload_location, |
270 upload_file_info->gdata_path), | 270 upload_file_info->drive_path), |
271 base::Bind(&GDataUploader::OnUploadLocationReceived, | 271 base::Bind(&DriveUploader::OnUploadLocationReceived, |
272 weak_ptr_factory_.GetWeakPtr(), | 272 weak_ptr_factory_.GetWeakPtr(), |
273 upload_file_info->upload_id)); | 273 upload_file_info->upload_id)); |
274 } | 274 } |
275 | 275 |
276 void GDataUploader::OnUploadLocationReceived( | 276 void DriveUploader::OnUploadLocationReceived( |
277 int upload_id, | 277 int upload_id, |
278 GDataErrorCode code, | 278 GDataErrorCode code, |
279 const GURL& upload_location) { | 279 const GURL& upload_location) { |
280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
281 | 281 |
282 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); | 282 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); |
283 if (!upload_file_info) | 283 if (!upload_file_info) |
284 return; | 284 return; |
285 | 285 |
286 DVLOG(1) << "Got upload location [" << upload_location.spec() | 286 DVLOG(1) << "Got upload location [" << upload_location.spec() |
287 << "] for [" << upload_file_info->title << "]"; | 287 << "] for [" << upload_file_info->title << "]"; |
288 | 288 |
289 if (code != HTTP_SUCCESS) { | 289 if (code != HTTP_SUCCESS) { |
290 // TODO(achuith): Handle error codes from Google Docs server. | 290 // TODO(achuith): Handle error codes from Google Docs server. |
291 UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info), | 291 UploadFailed(scoped_ptr<UploadFileInfo>(upload_file_info), |
292 DRIVE_FILE_ERROR_ABORT); | 292 DRIVE_FILE_ERROR_ABORT); |
293 return; | 293 return; |
294 } | 294 } |
295 | 295 |
296 upload_file_info->upload_location = upload_location; | 296 upload_file_info->upload_location = upload_location; |
297 | 297 |
298 // Start the upload from the beginning of the file. | 298 // Start the upload from the beginning of the file. |
299 UploadNextChunk(upload_file_info); | 299 UploadNextChunk(upload_file_info); |
300 } | 300 } |
301 | 301 |
302 void GDataUploader::UploadNextChunk(UploadFileInfo* upload_file_info) { | 302 void DriveUploader::UploadNextChunk(UploadFileInfo* upload_file_info) { |
303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
304 // Check that |upload_file_info| is in pending_uploads_. | 304 // Check that |upload_file_info| is in pending_uploads_. |
305 DCHECK(upload_file_info == GetUploadFileInfo(upload_file_info->upload_id)); | 305 DCHECK(upload_file_info == GetUploadFileInfo(upload_file_info->upload_id)); |
306 DVLOG(1) << "Number of pending uploads=" << pending_uploads_.size(); | 306 DVLOG(1) << "Number of pending uploads=" << pending_uploads_.size(); |
307 | 307 |
308 // Determine number of bytes to read for this upload iteration, which cannot | 308 // Determine number of bytes to read for this upload iteration, which cannot |
309 // exceed size of buf i.e. buf_len. | 309 // exceed size of buf i.e. buf_len. |
310 const int64 bytes_remaining = upload_file_info->SizeRemaining(); | 310 const int64 bytes_remaining = upload_file_info->SizeRemaining(); |
311 const int bytes_to_read = std::min(upload_file_info->SizeRemaining(), | 311 const int bytes_to_read = std::min(upload_file_info->SizeRemaining(), |
312 upload_file_info->buf_len); | 312 upload_file_info->buf_len); |
(...skipping 22 matching lines...) Expand all Loading... |
335 // Skips file_stream->Read and error checks for 0-byte case. Immediately | 335 // Skips file_stream->Read and error checks for 0-byte case. Immediately |
336 // proceeds to ResumeUpload. | 336 // proceeds to ResumeUpload. |
337 // TODO(kinaba): http://crbug.com/134814 | 337 // TODO(kinaba): http://crbug.com/134814 |
338 // Replace the following PostTask() to an direct method call. This is needed | 338 // Replace the following PostTask() to an direct method call. This is needed |
339 // because we have to ResumeUpload after the previous InitiateUpload or | 339 // because we have to ResumeUpload after the previous InitiateUpload or |
340 // ResumeUpload is completely finished; at this point, we are inside the | 340 // ResumeUpload is completely finished; at this point, we are inside the |
341 // callback function from the previous operation, which is not treated as | 341 // callback function from the previous operation, which is not treated as |
342 // finished yet. | 342 // finished yet. |
343 base::MessageLoopProxy::current()->PostTask( | 343 base::MessageLoopProxy::current()->PostTask( |
344 FROM_HERE, | 344 FROM_HERE, |
345 base::Bind(&GDataUploader::ResumeUpload, | 345 base::Bind(&DriveUploader::ResumeUpload, |
346 weak_ptr_factory_.GetWeakPtr(), | 346 weak_ptr_factory_.GetWeakPtr(), |
347 upload_file_info->upload_id)); | 347 upload_file_info->upload_id)); |
348 return; | 348 return; |
349 } | 349 } |
350 | 350 |
351 upload_file_info->file_stream->Read( | 351 upload_file_info->file_stream->Read( |
352 upload_file_info->buf, | 352 upload_file_info->buf, |
353 bytes_to_read, | 353 bytes_to_read, |
354 base::Bind(&GDataUploader::ReadCompletionCallback, | 354 base::Bind(&DriveUploader::ReadCompletionCallback, |
355 weak_ptr_factory_.GetWeakPtr(), | 355 weak_ptr_factory_.GetWeakPtr(), |
356 upload_file_info->upload_id, | 356 upload_file_info->upload_id, |
357 bytes_to_read)); | 357 bytes_to_read)); |
358 } | 358 } |
359 | 359 |
360 void GDataUploader::ReadCompletionCallback( | 360 void DriveUploader::ReadCompletionCallback( |
361 int upload_id, | 361 int upload_id, |
362 int bytes_to_read, | 362 int bytes_to_read, |
363 int bytes_read) { | 363 int bytes_read) { |
364 // The Read is asynchronously executed on BrowserThread::UI, where | 364 // The Read is asynchronously executed on BrowserThread::UI, where |
365 // Read() was called. | 365 // Read() was called. |
366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
367 DVLOG(1) << "ReadCompletionCallback bytes read=" << bytes_read; | 367 DVLOG(1) << "ReadCompletionCallback bytes read=" << bytes_read; |
368 | 368 |
369 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); | 369 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); |
370 if (!upload_file_info) | 370 if (!upload_file_info) |
371 return; | 371 return; |
372 | 372 |
373 // TODO(achuith): Handle this error. | 373 // TODO(achuith): Handle this error. |
374 DCHECK_EQ(bytes_to_read, bytes_read); | 374 DCHECK_EQ(bytes_to_read, bytes_read); |
375 DCHECK_GT(bytes_read, 0) << "Error reading from file " | 375 DCHECK_GT(bytes_read, 0) << "Error reading from file " |
376 << upload_file_info->file_path.value(); | 376 << upload_file_info->file_path.value(); |
377 | 377 |
378 upload_file_info->start_range = upload_file_info->end_range + 1; | 378 upload_file_info->start_range = upload_file_info->end_range + 1; |
379 upload_file_info->end_range = upload_file_info->start_range + | 379 upload_file_info->end_range = upload_file_info->start_range + |
380 bytes_read - 1; | 380 bytes_read - 1; |
381 | 381 |
382 ResumeUpload(upload_id); | 382 ResumeUpload(upload_id); |
383 } | 383 } |
384 | 384 |
385 void GDataUploader::ResumeUpload(int upload_id) { | 385 void DriveUploader::ResumeUpload(int upload_id) { |
386 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); | 386 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); |
387 if (!upload_file_info) | 387 if (!upload_file_info) |
388 return; | 388 return; |
389 | 389 |
390 drive_service_->ResumeUpload( | 390 drive_service_->ResumeUpload( |
391 ResumeUploadParams(upload_file_info->upload_mode, | 391 ResumeUploadParams(upload_file_info->upload_mode, |
392 upload_file_info->start_range, | 392 upload_file_info->start_range, |
393 upload_file_info->end_range, | 393 upload_file_info->end_range, |
394 upload_file_info->content_length, | 394 upload_file_info->content_length, |
395 upload_file_info->content_type, | 395 upload_file_info->content_type, |
396 upload_file_info->buf, | 396 upload_file_info->buf, |
397 upload_file_info->upload_location, | 397 upload_file_info->upload_location, |
398 upload_file_info->gdata_path), | 398 upload_file_info->drive_path), |
399 base::Bind(&GDataUploader::OnResumeUploadResponseReceived, | 399 base::Bind(&DriveUploader::OnResumeUploadResponseReceived, |
400 weak_ptr_factory_.GetWeakPtr(), | 400 weak_ptr_factory_.GetWeakPtr(), |
401 upload_file_info->upload_id)); | 401 upload_file_info->upload_id)); |
402 } | 402 } |
403 | 403 |
404 void GDataUploader::OnResumeUploadResponseReceived( | 404 void DriveUploader::OnResumeUploadResponseReceived( |
405 int upload_id, | 405 int upload_id, |
406 const ResumeUploadResponse& response, | 406 const ResumeUploadResponse& response, |
407 scoped_ptr<DocumentEntry> entry) { | 407 scoped_ptr<DocumentEntry> entry) { |
408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
409 | 409 |
410 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); | 410 UploadFileInfo* upload_file_info = GetUploadFileInfo(upload_id); |
411 if (!upload_file_info) | 411 if (!upload_file_info) |
412 return; | 412 return; |
413 | 413 |
414 const UploadMode upload_mode = upload_file_info->upload_mode; | 414 const UploadMode upload_mode = upload_file_info->upload_mode; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 } | 453 } |
454 | 454 |
455 DVLOG(1) << "Received range " << response.start_range_received | 455 DVLOG(1) << "Received range " << response.start_range_received |
456 << "-" << response.end_range_received | 456 << "-" << response.end_range_received |
457 << " for [" << upload_file_info->title << "]"; | 457 << " for [" << upload_file_info->title << "]"; |
458 | 458 |
459 // Continue uploading. | 459 // Continue uploading. |
460 UploadNextChunk(upload_file_info); | 460 UploadNextChunk(upload_file_info); |
461 } | 461 } |
462 | 462 |
463 void GDataUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info, | 463 void DriveUploader::UploadFailed(scoped_ptr<UploadFileInfo> upload_file_info, |
464 DriveFileError error) { | 464 DriveFileError error) { |
465 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 465 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
466 | 466 |
467 RemoveUpload(upload_file_info->upload_id); | 467 RemoveUpload(upload_file_info->upload_id); |
468 | 468 |
469 LOG(ERROR) << "Upload failed " << upload_file_info->DebugString(); | 469 LOG(ERROR) << "Upload failed " << upload_file_info->DebugString(); |
470 // This is subtle but we should take the callback reference before | 470 // This is subtle but we should take the callback reference before |
471 // calling upload_file_info.Pass(). Otherwise, it'll crash. | 471 // calling upload_file_info.Pass(). Otherwise, it'll crash. |
472 const UploadFileInfo::UploadCompletionCallback& callback = | 472 const UploadFileInfo::UploadCompletionCallback& callback = |
473 upload_file_info->completion_callback; | 473 upload_file_info->completion_callback; |
474 if (!callback.is_null()) | 474 if (!callback.is_null()) |
475 callback.Run(error, upload_file_info.Pass()); | 475 callback.Run(error, upload_file_info.Pass()); |
476 } | 476 } |
477 | 477 |
478 void GDataUploader::RemoveUpload(int upload_id) { | 478 void DriveUploader::RemoveUpload(int upload_id) { |
479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
480 pending_uploads_.erase(upload_id); | 480 pending_uploads_.erase(upload_id); |
481 } | 481 } |
482 | 482 |
483 } // namespace gdata | 483 } // namespace gdata |
OLD | NEW |