- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / google_apis / gdata_wapi_requests.cc
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/google_apis/gdata_wapi_requests.h"
6
7 #include "base/location.h"
8 #include "base/task_runner_util.h"
9 #include "base/values.h"
10 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
11 #include "chrome/browser/google_apis/gdata_wapi_url_generator.h"
12 #include "chrome/browser/google_apis/request_sender.h"
13 #include "chrome/browser/google_apis/request_util.h"
14 #include "third_party/libxml/chromium/libxml_utils.h"
15
16 using net::URLFetcher;
17
18 namespace google_apis {
19
20 namespace {
21
22 // Parses the JSON value to ResourceList.
23 scoped_ptr<ResourceList> ParseResourceListOnBlockingPool(
24     scoped_ptr<base::Value> value) {
25   DCHECK(value);
26
27   return ResourceList::ExtractAndParse(*value);
28 }
29
30 // Runs |callback| with |error| and |resource_list|, but replace the error code
31 // with GDATA_PARSE_ERROR, if there was a parsing error.
32 void DidParseResourceListOnBlockingPool(
33     const GetResourceListCallback& callback,
34     GDataErrorCode error,
35     scoped_ptr<ResourceList> resource_list) {
36   DCHECK(!callback.is_null());
37
38   // resource_list being NULL indicates there was a parsing error.
39   if (!resource_list)
40     error = GDATA_PARSE_ERROR;
41
42   callback.Run(error, resource_list.Pass());
43 }
44
45 // Parses the JSON value to ResourceList on the blocking pool and runs
46 // |callback| on the UI thread once parsing is done.
47 void ParseResourceListAndRun(
48     scoped_refptr<base::TaskRunner> blocking_task_runner,
49     const GetResourceListCallback& callback,
50     GDataErrorCode error,
51     scoped_ptr<base::Value> value) {
52   DCHECK(!callback.is_null());
53
54   if (!value) {
55     callback.Run(error, scoped_ptr<ResourceList>());
56     return;
57   }
58
59   base::PostTaskAndReplyWithResult(
60       blocking_task_runner,
61       FROM_HERE,
62       base::Bind(&ParseResourceListOnBlockingPool, base::Passed(&value)),
63       base::Bind(&DidParseResourceListOnBlockingPool, callback, error));
64 }
65
66 // Parses the JSON value to AccountMetadata and runs |callback| on the UI
67 // thread once parsing is done.
68 void ParseAccounetMetadataAndRun(const GetAccountMetadataCallback& callback,
69                                  GDataErrorCode error,
70                                  scoped_ptr<base::Value> value) {
71   DCHECK(!callback.is_null());
72
73   if (!value) {
74     callback.Run(error, scoped_ptr<AccountMetadata>());
75     return;
76   }
77
78   // Parsing AccountMetadata is cheap enough to do on UI thread.
79   scoped_ptr<AccountMetadata> entry =
80       google_apis::AccountMetadata::CreateFrom(*value);
81   if (!entry) {
82     callback.Run(GDATA_PARSE_ERROR, scoped_ptr<AccountMetadata>());
83     return;
84   }
85
86   callback.Run(error, entry.Pass());
87 }
88
89 // Parses the |value| to ResourceEntry with error handling.
90 // This is designed to be used for ResumeUploadRequest and
91 // GetUploadStatusRequest.
92 scoped_ptr<ResourceEntry> ParseResourceEntry(scoped_ptr<base::Value> value) {
93   scoped_ptr<ResourceEntry> entry;
94   if (value.get()) {
95     entry = ResourceEntry::ExtractAndParse(*value);
96
97     // Note: |value| may be NULL, in particular if the callback is for a
98     // failure.
99     if (!entry.get())
100       LOG(WARNING) << "Invalid entry received on upload.";
101   }
102
103   return entry.Pass();
104 }
105
106 // Extracts the open link url from the JSON Feed. Used by AuthorizeApp().
107 void ParseOpenLinkAndRun(const std::string& app_id,
108                          const AuthorizeAppCallback& callback,
109                          GDataErrorCode error,
110                          scoped_ptr<base::Value> value) {
111   DCHECK(!callback.is_null());
112
113   if (!value) {
114     callback.Run(error, GURL());
115     return;
116   }
117
118   // Parsing ResourceEntry is cheap enough to do on UI thread.
119   scoped_ptr<ResourceEntry> resource_entry = ParseResourceEntry(value.Pass());
120   if (!resource_entry) {
121     callback.Run(GDATA_PARSE_ERROR, GURL());
122     return;
123   }
124
125   // Look for the link to open the file with the app with |app_id|.
126   const ScopedVector<Link>& resource_links = resource_entry->links();
127   GURL open_link;
128   for (size_t i = 0; i < resource_links.size(); ++i) {
129     const Link& link = *resource_links[i];
130     if (link.type() == Link::LINK_OPEN_WITH && link.app_id() == app_id) {
131       open_link = link.href();
132       break;
133     }
134   }
135
136   if (open_link.is_empty())
137     error = GDATA_OTHER_ERROR;
138
139   callback.Run(error, open_link);
140 }
141
142 }  // namespace
143
144 //============================ GetResourceListRequest ========================
145
146 GetResourceListRequest::GetResourceListRequest(
147     RequestSender* sender,
148     const GDataWapiUrlGenerator& url_generator,
149     const GURL& override_url,
150     int64 start_changestamp,
151     const std::string& search_string,
152     const std::string& directory_resource_id,
153     const GetResourceListCallback& callback)
154     : GetDataRequest(
155           sender,
156           base::Bind(&ParseResourceListAndRun,
157                      make_scoped_refptr(sender->blocking_task_runner()),
158                      callback)),
159       url_generator_(url_generator),
160       override_url_(override_url),
161       start_changestamp_(start_changestamp),
162       search_string_(search_string),
163       directory_resource_id_(directory_resource_id) {
164   DCHECK(!callback.is_null());
165 }
166
167 GetResourceListRequest::~GetResourceListRequest() {}
168
169 GURL GetResourceListRequest::GetURL() const {
170   return url_generator_.GenerateResourceListUrl(override_url_,
171                                                 start_changestamp_,
172                                                 search_string_,
173                                                 directory_resource_id_);
174 }
175
176 //============================ SearchByTitleRequest ==========================
177
178 SearchByTitleRequest::SearchByTitleRequest(
179     RequestSender* sender,
180     const GDataWapiUrlGenerator& url_generator,
181     const std::string& title,
182     const std::string& directory_resource_id,
183     const GetResourceListCallback& callback)
184     : GetDataRequest(
185           sender,
186           base::Bind(&ParseResourceListAndRun,
187                      make_scoped_refptr(sender->blocking_task_runner()),
188                      callback)),
189       url_generator_(url_generator),
190       title_(title),
191       directory_resource_id_(directory_resource_id) {
192   DCHECK(!callback.is_null());
193 }
194
195 SearchByTitleRequest::~SearchByTitleRequest() {}
196
197 GURL SearchByTitleRequest::GetURL() const {
198   return url_generator_.GenerateSearchByTitleUrl(
199       title_, directory_resource_id_);
200 }
201
202 //============================ GetResourceEntryRequest =======================
203
204 GetResourceEntryRequest::GetResourceEntryRequest(
205     RequestSender* sender,
206     const GDataWapiUrlGenerator& url_generator,
207     const std::string& resource_id,
208     const GURL& embed_origin,
209     const GetDataCallback& callback)
210     : GetDataRequest(sender, callback),
211       url_generator_(url_generator),
212       resource_id_(resource_id),
213       embed_origin_(embed_origin) {
214   DCHECK(!callback.is_null());
215 }
216
217 GetResourceEntryRequest::~GetResourceEntryRequest() {}
218
219 GURL GetResourceEntryRequest::GetURL() const {
220   return url_generator_.GenerateEditUrlWithEmbedOrigin(
221       resource_id_, embed_origin_);
222 }
223
224 //========================= GetAccountMetadataRequest ========================
225
226 GetAccountMetadataRequest::GetAccountMetadataRequest(
227     RequestSender* sender,
228     const GDataWapiUrlGenerator& url_generator,
229     const GetAccountMetadataCallback& callback,
230     bool include_installed_apps)
231     : GetDataRequest(sender,
232                      base::Bind(&ParseAccounetMetadataAndRun, callback)),
233       url_generator_(url_generator),
234       include_installed_apps_(include_installed_apps) {
235   DCHECK(!callback.is_null());
236 }
237
238 GetAccountMetadataRequest::~GetAccountMetadataRequest() {}
239
240 GURL GetAccountMetadataRequest::GetURL() const {
241   return url_generator_.GenerateAccountMetadataUrl(include_installed_apps_);
242 }
243
244 //=========================== DeleteResourceRequest ==========================
245
246 DeleteResourceRequest::DeleteResourceRequest(
247     RequestSender* sender,
248     const GDataWapiUrlGenerator& url_generator,
249     const EntryActionCallback& callback,
250     const std::string& resource_id,
251     const std::string& etag)
252     : EntryActionRequest(sender, callback),
253       url_generator_(url_generator),
254       resource_id_(resource_id),
255       etag_(etag) {
256   DCHECK(!callback.is_null());
257 }
258
259 DeleteResourceRequest::~DeleteResourceRequest() {}
260
261 GURL DeleteResourceRequest::GetURL() const {
262   return url_generator_.GenerateEditUrl(resource_id_);
263 }
264
265 URLFetcher::RequestType DeleteResourceRequest::GetRequestType() const {
266   return URLFetcher::DELETE_REQUEST;
267 }
268
269 std::vector<std::string>
270 DeleteResourceRequest::GetExtraRequestHeaders() const {
271   std::vector<std::string> headers;
272   headers.push_back(util::GenerateIfMatchHeader(etag_));
273   return headers;
274 }
275
276 //========================== CreateDirectoryRequest ==========================
277
278 CreateDirectoryRequest::CreateDirectoryRequest(
279     RequestSender* sender,
280     const GDataWapiUrlGenerator& url_generator,
281     const GetDataCallback& callback,
282     const std::string& parent_resource_id,
283     const std::string& directory_title)
284     : GetDataRequest(sender, callback),
285       url_generator_(url_generator),
286       parent_resource_id_(parent_resource_id),
287       directory_title_(directory_title) {
288   DCHECK(!callback.is_null());
289 }
290
291 CreateDirectoryRequest::~CreateDirectoryRequest() {}
292
293 GURL CreateDirectoryRequest::GetURL() const {
294   return url_generator_.GenerateContentUrl(parent_resource_id_);
295 }
296
297 URLFetcher::RequestType
298 CreateDirectoryRequest::GetRequestType() const {
299   return URLFetcher::POST;
300 }
301
302 bool CreateDirectoryRequest::GetContentData(std::string* upload_content_type,
303                                             std::string* upload_content) {
304   upload_content_type->assign("application/atom+xml");
305   XmlWriter xml_writer;
306   xml_writer.StartWriting();
307   xml_writer.StartElement("entry");
308   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
309
310   xml_writer.StartElement("category");
311   xml_writer.AddAttribute("scheme",
312                           "http://schemas.google.com/g/2005#kind");
313   xml_writer.AddAttribute("term",
314                           "http://schemas.google.com/docs/2007#folder");
315   xml_writer.EndElement();  // Ends "category" element.
316
317   xml_writer.WriteElement("title", directory_title_);
318
319   xml_writer.EndElement();  // Ends "entry" element.
320   xml_writer.StopWriting();
321   upload_content->assign(xml_writer.GetWrittenString());
322   DVLOG(1) << "CreateDirectory data: " << *upload_content_type << ", ["
323            << *upload_content << "]";
324   return true;
325 }
326
327 //============================ CopyHostedDocumentRequest =====================
328
329 CopyHostedDocumentRequest::CopyHostedDocumentRequest(
330     RequestSender* sender,
331     const GDataWapiUrlGenerator& url_generator,
332     const GetDataCallback& callback,
333     const std::string& resource_id,
334     const std::string& new_title)
335     : GetDataRequest(sender, callback),
336       url_generator_(url_generator),
337       resource_id_(resource_id),
338       new_title_(new_title) {
339   DCHECK(!callback.is_null());
340 }
341
342 CopyHostedDocumentRequest::~CopyHostedDocumentRequest() {}
343
344 URLFetcher::RequestType CopyHostedDocumentRequest::GetRequestType() const {
345   return URLFetcher::POST;
346 }
347
348 GURL CopyHostedDocumentRequest::GetURL() const {
349   return url_generator_.GenerateResourceListRootUrl();
350 }
351
352 bool CopyHostedDocumentRequest::GetContentData(
353     std::string* upload_content_type,
354     std::string* upload_content) {
355   upload_content_type->assign("application/atom+xml");
356   XmlWriter xml_writer;
357   xml_writer.StartWriting();
358   xml_writer.StartElement("entry");
359   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
360
361   xml_writer.WriteElement("id", resource_id_);
362   xml_writer.WriteElement("title", new_title_);
363
364   xml_writer.EndElement();  // Ends "entry" element.
365   xml_writer.StopWriting();
366   upload_content->assign(xml_writer.GetWrittenString());
367   DVLOG(1) << "CopyHostedDocumentRequest data: " << *upload_content_type
368            << ", [" << *upload_content << "]";
369   return true;
370 }
371
372 //=========================== RenameResourceRequest ==========================
373
374 RenameResourceRequest::RenameResourceRequest(
375     RequestSender* sender,
376     const GDataWapiUrlGenerator& url_generator,
377     const EntryActionCallback& callback,
378     const std::string& resource_id,
379     const std::string& new_title)
380     : EntryActionRequest(sender, callback),
381       url_generator_(url_generator),
382       resource_id_(resource_id),
383       new_title_(new_title) {
384   DCHECK(!callback.is_null());
385 }
386
387 RenameResourceRequest::~RenameResourceRequest() {}
388
389 URLFetcher::RequestType RenameResourceRequest::GetRequestType() const {
390   return URLFetcher::PUT;
391 }
392
393 std::vector<std::string>
394 RenameResourceRequest::GetExtraRequestHeaders() const {
395   std::vector<std::string> headers;
396   headers.push_back(util::kIfMatchAllHeader);
397   return headers;
398 }
399
400 GURL RenameResourceRequest::GetURL() const {
401   return url_generator_.GenerateEditUrl(resource_id_);
402 }
403
404 bool RenameResourceRequest::GetContentData(std::string* upload_content_type,
405                                            std::string* upload_content) {
406   upload_content_type->assign("application/atom+xml");
407   XmlWriter xml_writer;
408   xml_writer.StartWriting();
409   xml_writer.StartElement("entry");
410   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
411
412   xml_writer.WriteElement("title", new_title_);
413
414   xml_writer.EndElement();  // Ends "entry" element.
415   xml_writer.StopWriting();
416   upload_content->assign(xml_writer.GetWrittenString());
417   DVLOG(1) << "RenameResourceRequest data: " << *upload_content_type << ", ["
418            << *upload_content << "]";
419   return true;
420 }
421
422 //=========================== AuthorizeAppRequest ==========================
423
424 AuthorizeAppRequest::AuthorizeAppRequest(
425     RequestSender* sender,
426     const GDataWapiUrlGenerator& url_generator,
427     const AuthorizeAppCallback& callback,
428     const std::string& resource_id,
429     const std::string& app_id)
430     : GetDataRequest(sender,
431                      base::Bind(&ParseOpenLinkAndRun, app_id, callback)),
432       url_generator_(url_generator),
433       resource_id_(resource_id),
434       app_id_(app_id) {
435   DCHECK(!callback.is_null());
436 }
437
438 AuthorizeAppRequest::~AuthorizeAppRequest() {}
439
440 URLFetcher::RequestType AuthorizeAppRequest::GetRequestType() const {
441   return URLFetcher::PUT;
442 }
443
444 std::vector<std::string>
445 AuthorizeAppRequest::GetExtraRequestHeaders() const {
446   std::vector<std::string> headers;
447   headers.push_back(util::kIfMatchAllHeader);
448   return headers;
449 }
450
451 bool AuthorizeAppRequest::GetContentData(std::string* upload_content_type,
452                                          std::string* upload_content) {
453   upload_content_type->assign("application/atom+xml");
454   XmlWriter xml_writer;
455   xml_writer.StartWriting();
456   xml_writer.StartElement("entry");
457   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
458   xml_writer.AddAttribute("xmlns:docs", "http://schemas.google.com/docs/2007");
459   xml_writer.WriteElement("docs:authorizedApp", app_id_);
460
461   xml_writer.EndElement();  // Ends "entry" element.
462   xml_writer.StopWriting();
463   upload_content->assign(xml_writer.GetWrittenString());
464   DVLOG(1) << "AuthorizeAppRequest data: " << *upload_content_type << ", ["
465            << *upload_content << "]";
466   return true;
467 }
468
469 GURL AuthorizeAppRequest::GetURL() const {
470   return url_generator_.GenerateEditUrl(resource_id_);
471 }
472
473 //======================= AddResourceToDirectoryRequest ======================
474
475 AddResourceToDirectoryRequest::AddResourceToDirectoryRequest(
476     RequestSender* sender,
477     const GDataWapiUrlGenerator& url_generator,
478     const EntryActionCallback& callback,
479     const std::string& parent_resource_id,
480     const std::string& resource_id)
481     : EntryActionRequest(sender, callback),
482       url_generator_(url_generator),
483       parent_resource_id_(parent_resource_id),
484       resource_id_(resource_id) {
485   DCHECK(!callback.is_null());
486 }
487
488 AddResourceToDirectoryRequest::~AddResourceToDirectoryRequest() {}
489
490 GURL AddResourceToDirectoryRequest::GetURL() const {
491   return url_generator_.GenerateContentUrl(parent_resource_id_);
492 }
493
494 URLFetcher::RequestType
495 AddResourceToDirectoryRequest::GetRequestType() const {
496   return URLFetcher::POST;
497 }
498
499 bool AddResourceToDirectoryRequest::GetContentData(
500     std::string* upload_content_type, std::string* upload_content) {
501   upload_content_type->assign("application/atom+xml");
502   XmlWriter xml_writer;
503   xml_writer.StartWriting();
504   xml_writer.StartElement("entry");
505   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
506
507   xml_writer.WriteElement(
508       "id", url_generator_.GenerateEditUrlWithoutParams(resource_id_).spec());
509
510   xml_writer.EndElement();  // Ends "entry" element.
511   xml_writer.StopWriting();
512   upload_content->assign(xml_writer.GetWrittenString());
513   DVLOG(1) << "AddResourceToDirectoryRequest data: " << *upload_content_type
514            << ", [" << *upload_content << "]";
515   return true;
516 }
517
518 //==================== RemoveResourceFromDirectoryRequest ====================
519
520 RemoveResourceFromDirectoryRequest::RemoveResourceFromDirectoryRequest(
521     RequestSender* sender,
522     const GDataWapiUrlGenerator& url_generator,
523     const EntryActionCallback& callback,
524     const std::string& parent_resource_id,
525     const std::string& document_resource_id)
526     : EntryActionRequest(sender, callback),
527       url_generator_(url_generator),
528       resource_id_(document_resource_id),
529       parent_resource_id_(parent_resource_id) {
530   DCHECK(!callback.is_null());
531 }
532
533 RemoveResourceFromDirectoryRequest::~RemoveResourceFromDirectoryRequest() {
534 }
535
536 GURL RemoveResourceFromDirectoryRequest::GetURL() const {
537   return url_generator_.GenerateResourceUrlForRemoval(
538       parent_resource_id_, resource_id_);
539 }
540
541 URLFetcher::RequestType
542 RemoveResourceFromDirectoryRequest::GetRequestType() const {
543   return URLFetcher::DELETE_REQUEST;
544 }
545
546 std::vector<std::string>
547 RemoveResourceFromDirectoryRequest::GetExtraRequestHeaders() const {
548   std::vector<std::string> headers;
549   headers.push_back(util::kIfMatchAllHeader);
550   return headers;
551 }
552
553 //======================= InitiateUploadNewFileRequest =======================
554
555 InitiateUploadNewFileRequest::InitiateUploadNewFileRequest(
556     RequestSender* sender,
557     const GDataWapiUrlGenerator& url_generator,
558     const InitiateUploadCallback& callback,
559     const std::string& content_type,
560     int64 content_length,
561     const std::string& parent_resource_id,
562     const std::string& title)
563     : InitiateUploadRequestBase(sender, callback, content_type, content_length),
564       url_generator_(url_generator),
565       parent_resource_id_(parent_resource_id),
566       title_(title) {
567 }
568
569 InitiateUploadNewFileRequest::~InitiateUploadNewFileRequest() {}
570
571 GURL InitiateUploadNewFileRequest::GetURL() const {
572   return url_generator_.GenerateInitiateUploadNewFileUrl(parent_resource_id_);
573 }
574
575 net::URLFetcher::RequestType
576 InitiateUploadNewFileRequest::GetRequestType() const {
577   return net::URLFetcher::POST;
578 }
579
580 bool InitiateUploadNewFileRequest::GetContentData(
581     std::string* upload_content_type,
582     std::string* upload_content) {
583   upload_content_type->assign("application/atom+xml");
584   XmlWriter xml_writer;
585   xml_writer.StartWriting();
586   xml_writer.StartElement("entry");
587   xml_writer.AddAttribute("xmlns", "http://www.w3.org/2005/Atom");
588   xml_writer.AddAttribute("xmlns:docs",
589                           "http://schemas.google.com/docs/2007");
590   xml_writer.WriteElement("title", title_);
591   xml_writer.EndElement();  // Ends "entry" element.
592   xml_writer.StopWriting();
593   upload_content->assign(xml_writer.GetWrittenString());
594   DVLOG(1) << "InitiateUploadNewFile: " << *upload_content_type << ", ["
595            << *upload_content << "]";
596   return true;
597 }
598
599 //===================== InitiateUploadExistingFileRequest ====================
600
601 InitiateUploadExistingFileRequest::InitiateUploadExistingFileRequest(
602     RequestSender* sender,
603     const GDataWapiUrlGenerator& url_generator,
604     const InitiateUploadCallback& callback,
605     const std::string& content_type,
606     int64 content_length,
607     const std::string& resource_id,
608     const std::string& etag)
609     : InitiateUploadRequestBase(sender, callback, content_type, content_length),
610       url_generator_(url_generator),
611       resource_id_(resource_id),
612       etag_(etag) {
613 }
614
615 InitiateUploadExistingFileRequest::~InitiateUploadExistingFileRequest() {}
616
617 GURL InitiateUploadExistingFileRequest::GetURL() const {
618   return url_generator_.GenerateInitiateUploadExistingFileUrl(resource_id_);
619 }
620
621 net::URLFetcher::RequestType
622 InitiateUploadExistingFileRequest::GetRequestType() const {
623   return net::URLFetcher::PUT;
624 }
625
626 bool InitiateUploadExistingFileRequest::GetContentData(
627     std::string* upload_content_type,
628     std::string* upload_content) {
629   // According to the document there is no need to send the content-type.
630   // However, the server would return 500 server error without the
631   // content-type.
632   // As its workaround, send "text/plain" content-type here.
633   *upload_content_type = "text/plain";
634   *upload_content = "";
635   return true;
636 }
637
638 std::vector<std::string>
639 InitiateUploadExistingFileRequest::GetExtraRequestHeaders() const {
640   std::vector<std::string> headers(
641       InitiateUploadRequestBase::GetExtraRequestHeaders());
642   headers.push_back(util::GenerateIfMatchHeader(etag_));
643   return headers;
644 }
645
646 //============================ ResumeUploadRequest ===========================
647
648 ResumeUploadRequest::ResumeUploadRequest(
649     RequestSender* sender,
650     const UploadRangeCallback& callback,
651     const ProgressCallback& progress_callback,
652     const GURL& upload_location,
653     int64 start_position,
654     int64 end_position,
655     int64 content_length,
656     const std::string& content_type,
657     const base::FilePath& local_file_path)
658     : ResumeUploadRequestBase(sender,
659                               upload_location,
660                               start_position,
661                               end_position,
662                               content_length,
663                               content_type,
664                               local_file_path),
665       callback_(callback),
666       progress_callback_(progress_callback) {
667   DCHECK(!callback_.is_null());
668 }
669
670 ResumeUploadRequest::~ResumeUploadRequest() {}
671
672 void ResumeUploadRequest::OnRangeRequestComplete(
673     const UploadRangeResponse& response, scoped_ptr<base::Value> value) {
674   callback_.Run(response, ParseResourceEntry(value.Pass()));
675 }
676
677 void ResumeUploadRequest::OnURLFetchUploadProgress(
678     const URLFetcher* source, int64 current, int64 total) {
679   if (!progress_callback_.is_null())
680     progress_callback_.Run(current, total);
681 }
682
683 //========================== GetUploadStatusRequest ==========================
684
685 GetUploadStatusRequest::GetUploadStatusRequest(
686     RequestSender* sender,
687     const UploadRangeCallback& callback,
688     const GURL& upload_url,
689     int64 content_length)
690     : GetUploadStatusRequestBase(sender, upload_url, content_length),
691       callback_(callback) {
692   DCHECK(!callback.is_null());
693 }
694
695 GetUploadStatusRequest::~GetUploadStatusRequest() {}
696
697 void GetUploadStatusRequest::OnRangeRequestComplete(
698     const UploadRangeResponse& response, scoped_ptr<base::Value> value) {
699   callback_.Run(response, ParseResourceEntry(value.Pass()));
700 }
701
702 //========================== DownloadFileRequest ==========================
703
704 DownloadFileRequest::DownloadFileRequest(
705     RequestSender* sender,
706     const GDataWapiUrlGenerator& url_generator,
707     const DownloadActionCallback& download_action_callback,
708     const GetContentCallback& get_content_callback,
709     const ProgressCallback& progress_callback,
710     const std::string& resource_id,
711     const base::FilePath& output_file_path)
712     : DownloadFileRequestBase(
713           sender,
714           download_action_callback,
715           get_content_callback,
716           progress_callback,
717           url_generator.GenerateDownloadFileUrl(resource_id),
718           output_file_path) {
719 }
720
721 DownloadFileRequest::~DownloadFileRequest() {
722 }
723
724 }  // namespace google_apis