Home | History | Annotate | Download | only in drive
      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 "google_apis/drive/drive_api_requests.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback.h"
      9 #include "base/json/json_writer.h"
     10 #include "base/location.h"
     11 #include "base/sequenced_task_runner.h"
     12 #include "base/task_runner_util.h"
     13 #include "base/values.h"
     14 #include "google_apis/drive/drive_api_parser.h"
     15 #include "google_apis/drive/request_sender.h"
     16 #include "google_apis/drive/request_util.h"
     17 #include "google_apis/drive/time_util.h"
     18 #include "net/base/url_util.h"
     19 
     20 namespace google_apis {
     21 namespace {
     22 
     23 const char kContentTypeApplicationJson[] = "application/json";
     24 const char kParentLinkKind[] = "drive#fileLink";
     25 
     26 // Parses the JSON value to a resource typed |T| and runs |callback| on the UI
     27 // thread once parsing is done.
     28 template<typename T>
     29 void ParseJsonAndRun(
     30     const base::Callback<void(GDataErrorCode, scoped_ptr<T>)>& callback,
     31     GDataErrorCode error,
     32     scoped_ptr<base::Value> value) {
     33   DCHECK(!callback.is_null());
     34 
     35   scoped_ptr<T> resource;
     36   if (value) {
     37     resource = T::CreateFrom(*value);
     38     if (!resource) {
     39       // Failed to parse the JSON value, although the JSON value is available,
     40       // so let the callback know the parsing error.
     41       error = GDATA_PARSE_ERROR;
     42     }
     43   }
     44 
     45   callback.Run(error, resource.Pass());
     46 }
     47 
     48 // Thin adapter of T::CreateFrom.
     49 template<typename T>
     50 scoped_ptr<T> ParseJsonOnBlockingPool(scoped_ptr<base::Value> value) {
     51   return T::CreateFrom(*value);
     52 }
     53 
     54 // Runs |callback| with given |error| and |value|. If |value| is null,
     55 // overwrites |error| to GDATA_PARSE_ERROR.
     56 template<typename T>
     57 void ParseJsonOnBlockingPoolAndRunAfterBlockingPoolTask(
     58     const base::Callback<void(GDataErrorCode, scoped_ptr<T>)>& callback,
     59     GDataErrorCode error, scoped_ptr<T> value) {
     60   if (!value)
     61     error = GDATA_PARSE_ERROR;
     62   callback.Run(error, value.Pass());
     63 }
     64 
     65 // Parses the JSON value to a resource typed |T| and runs |callback| on
     66 // blocking pool, and then run on the current thread.
     67 // TODO(hidehiko): Move this and ParseJsonAndRun defined above into base with
     68 // merging the tasks running on blocking pool into one.
     69 template<typename T>
     70 void ParseJsonOnBlockingPoolAndRun(
     71     scoped_refptr<base::TaskRunner> blocking_task_runner,
     72     const base::Callback<void(GDataErrorCode, scoped_ptr<T>)>& callback,
     73     GDataErrorCode error,
     74     scoped_ptr<base::Value> value) {
     75   DCHECK(!callback.is_null());
     76 
     77   if (!value) {
     78     callback.Run(error, scoped_ptr<T>());
     79     return;
     80   }
     81 
     82   base::PostTaskAndReplyWithResult(
     83       blocking_task_runner,
     84       FROM_HERE,
     85       base::Bind(&ParseJsonOnBlockingPool<T>, base::Passed(&value)),
     86       base::Bind(&ParseJsonOnBlockingPoolAndRunAfterBlockingPoolTask<T>,
     87                  callback, error));
     88 }
     89 
     90 // Parses the JSON value to FileResource instance and runs |callback| on the
     91 // UI thread once parsing is done.
     92 // This is customized version of ParseJsonAndRun defined above to adapt the
     93 // remaining response type.
     94 void ParseFileResourceWithUploadRangeAndRun(
     95     const drive::UploadRangeCallback& callback,
     96     const UploadRangeResponse& response,
     97     scoped_ptr<base::Value> value) {
     98   DCHECK(!callback.is_null());
     99 
    100   scoped_ptr<FileResource> file_resource;
    101   if (value) {
    102     file_resource = FileResource::CreateFrom(*value);
    103     if (!file_resource) {
    104       callback.Run(
    105           UploadRangeResponse(GDATA_PARSE_ERROR,
    106                               response.start_position_received,
    107                               response.end_position_received),
    108           scoped_ptr<FileResource>());
    109       return;
    110     }
    111   }
    112 
    113   callback.Run(response, file_resource.Pass());
    114 }
    115 
    116 }  // namespace
    117 
    118 namespace drive {
    119 
    120 //============================ DriveApiDataRequest ===========================
    121 
    122 DriveApiDataRequest::DriveApiDataRequest(RequestSender* sender,
    123                                          const GetDataCallback& callback)
    124     : GetDataRequest(sender, callback) {
    125 }
    126 
    127 DriveApiDataRequest::~DriveApiDataRequest() {
    128 }
    129 
    130 GURL DriveApiDataRequest::GetURL() const {
    131   GURL url = GetURLInternal();
    132   if (!fields_.empty())
    133     url = net::AppendOrReplaceQueryParameter(url, "fields", fields_);
    134   return url;
    135 }
    136 
    137 //=============================== FilesGetRequest =============================
    138 
    139 FilesGetRequest::FilesGetRequest(
    140     RequestSender* sender,
    141     const DriveApiUrlGenerator& url_generator,
    142     const FileResourceCallback& callback)
    143     : DriveApiDataRequest(
    144           sender,
    145           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
    146       url_generator_(url_generator) {
    147   DCHECK(!callback.is_null());
    148 }
    149 
    150 FilesGetRequest::~FilesGetRequest() {}
    151 
    152 GURL FilesGetRequest::GetURLInternal() const {
    153   return url_generator_.GetFilesGetUrl(file_id_);
    154 }
    155 
    156 //============================ FilesInsertRequest ============================
    157 
    158 FilesInsertRequest::FilesInsertRequest(
    159     RequestSender* sender,
    160     const DriveApiUrlGenerator& url_generator,
    161     const FileResourceCallback& callback)
    162     : DriveApiDataRequest(
    163           sender,
    164           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
    165       url_generator_(url_generator) {
    166   DCHECK(!callback.is_null());
    167 }
    168 
    169 FilesInsertRequest::~FilesInsertRequest() {}
    170 
    171 net::URLFetcher::RequestType FilesInsertRequest::GetRequestType() const {
    172   return net::URLFetcher::POST;
    173 }
    174 
    175 bool FilesInsertRequest::GetContentData(std::string* upload_content_type,
    176                                         std::string* upload_content) {
    177   *upload_content_type = kContentTypeApplicationJson;
    178 
    179   base::DictionaryValue root;
    180 
    181   if (!mime_type_.empty())
    182     root.SetString("mimeType", mime_type_);
    183 
    184   if (!parents_.empty()) {
    185     base::ListValue* parents_value = new base::ListValue;
    186     for (size_t i = 0; i < parents_.size(); ++i) {
    187       base::DictionaryValue* parent = new base::DictionaryValue;
    188       parent->SetString("id", parents_[i]);
    189       parents_value->Append(parent);
    190     }
    191     root.Set("parents", parents_value);
    192   }
    193 
    194   if (!title_.empty())
    195     root.SetString("title", title_);
    196 
    197   base::JSONWriter::Write(&root, upload_content);
    198   DVLOG(1) << "FilesInsert data: " << *upload_content_type << ", ["
    199            << *upload_content << "]";
    200   return true;
    201 }
    202 
    203 GURL FilesInsertRequest::GetURLInternal() const {
    204   return url_generator_.GetFilesInsertUrl();
    205 }
    206 
    207 //============================== FilesPatchRequest ============================
    208 
    209 FilesPatchRequest::FilesPatchRequest(
    210     RequestSender* sender,
    211     const DriveApiUrlGenerator& url_generator,
    212     const FileResourceCallback& callback)
    213     : DriveApiDataRequest(
    214           sender,
    215           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
    216       url_generator_(url_generator),
    217       set_modified_date_(false),
    218       update_viewed_date_(true) {
    219   DCHECK(!callback.is_null());
    220 }
    221 
    222 FilesPatchRequest::~FilesPatchRequest() {}
    223 
    224 net::URLFetcher::RequestType FilesPatchRequest::GetRequestType() const {
    225   return net::URLFetcher::PATCH;
    226 }
    227 
    228 std::vector<std::string> FilesPatchRequest::GetExtraRequestHeaders() const {
    229   std::vector<std::string> headers;
    230   headers.push_back(util::kIfMatchAllHeader);
    231   return headers;
    232 }
    233 
    234 GURL FilesPatchRequest::GetURLInternal() const {
    235   return url_generator_.GetFilesPatchUrl(
    236       file_id_, set_modified_date_, update_viewed_date_);
    237 }
    238 
    239 bool FilesPatchRequest::GetContentData(std::string* upload_content_type,
    240                                        std::string* upload_content) {
    241   if (title_.empty() &&
    242       modified_date_.is_null() &&
    243       last_viewed_by_me_date_.is_null() &&
    244       parents_.empty())
    245     return false;
    246 
    247   *upload_content_type = kContentTypeApplicationJson;
    248 
    249   base::DictionaryValue root;
    250   if (!title_.empty())
    251     root.SetString("title", title_);
    252 
    253   if (!modified_date_.is_null())
    254     root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
    255 
    256   if (!last_viewed_by_me_date_.is_null()) {
    257     root.SetString("lastViewedByMeDate",
    258                    util::FormatTimeAsString(last_viewed_by_me_date_));
    259   }
    260 
    261   if (!parents_.empty()) {
    262     base::ListValue* parents_value = new base::ListValue;
    263     for (size_t i = 0; i < parents_.size(); ++i) {
    264       base::DictionaryValue* parent = new base::DictionaryValue;
    265       parent->SetString("id", parents_[i]);
    266       parents_value->Append(parent);
    267     }
    268     root.Set("parents", parents_value);
    269   }
    270 
    271   base::JSONWriter::Write(&root, upload_content);
    272   DVLOG(1) << "FilesPatch data: " << *upload_content_type << ", ["
    273            << *upload_content << "]";
    274   return true;
    275 }
    276 
    277 //============================= FilesCopyRequest ==============================
    278 
    279 FilesCopyRequest::FilesCopyRequest(
    280     RequestSender* sender,
    281     const DriveApiUrlGenerator& url_generator,
    282     const FileResourceCallback& callback)
    283     : DriveApiDataRequest(
    284           sender,
    285           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
    286       url_generator_(url_generator) {
    287   DCHECK(!callback.is_null());
    288 }
    289 
    290 FilesCopyRequest::~FilesCopyRequest() {
    291 }
    292 
    293 net::URLFetcher::RequestType FilesCopyRequest::GetRequestType() const {
    294   return net::URLFetcher::POST;
    295 }
    296 
    297 GURL FilesCopyRequest::GetURLInternal() const {
    298   return url_generator_.GetFilesCopyUrl(file_id_);
    299 }
    300 
    301 bool FilesCopyRequest::GetContentData(std::string* upload_content_type,
    302                                       std::string* upload_content) {
    303   if (parents_.empty() && title_.empty())
    304     return false;
    305 
    306   *upload_content_type = kContentTypeApplicationJson;
    307 
    308   base::DictionaryValue root;
    309 
    310   if (!modified_date_.is_null())
    311     root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
    312 
    313   if (!parents_.empty()) {
    314     base::ListValue* parents_value = new base::ListValue;
    315     for (size_t i = 0; i < parents_.size(); ++i) {
    316       base::DictionaryValue* parent = new base::DictionaryValue;
    317       parent->SetString("id", parents_[i]);
    318       parents_value->Append(parent);
    319     }
    320     root.Set("parents", parents_value);
    321   }
    322 
    323   if (!title_.empty())
    324     root.SetString("title", title_);
    325 
    326   base::JSONWriter::Write(&root, upload_content);
    327   DVLOG(1) << "FilesCopy data: " << *upload_content_type << ", ["
    328            << *upload_content << "]";
    329   return true;
    330 }
    331 
    332 //============================= FilesListRequest =============================
    333 
    334 FilesListRequest::FilesListRequest(
    335     RequestSender* sender,
    336     const DriveApiUrlGenerator& url_generator,
    337     const FileListCallback& callback)
    338     : DriveApiDataRequest(
    339           sender,
    340           base::Bind(&ParseJsonOnBlockingPoolAndRun<FileList>,
    341                      make_scoped_refptr(sender->blocking_task_runner()),
    342                      callback)),
    343       url_generator_(url_generator),
    344       max_results_(100) {
    345   DCHECK(!callback.is_null());
    346 }
    347 
    348 FilesListRequest::~FilesListRequest() {}
    349 
    350 GURL FilesListRequest::GetURLInternal() const {
    351   return url_generator_.GetFilesListUrl(max_results_, page_token_, q_);
    352 }
    353 
    354 //======================== FilesListNextPageRequest =========================
    355 
    356 FilesListNextPageRequest::FilesListNextPageRequest(
    357     RequestSender* sender,
    358     const FileListCallback& callback)
    359     : DriveApiDataRequest(
    360           sender,
    361           base::Bind(&ParseJsonOnBlockingPoolAndRun<FileList>,
    362                      make_scoped_refptr(sender->blocking_task_runner()),
    363                      callback)) {
    364   DCHECK(!callback.is_null());
    365 }
    366 
    367 FilesListNextPageRequest::~FilesListNextPageRequest() {
    368 }
    369 
    370 GURL FilesListNextPageRequest::GetURLInternal() const {
    371   return next_link_;
    372 }
    373 
    374 //============================ FilesDeleteRequest =============================
    375 
    376 FilesDeleteRequest::FilesDeleteRequest(
    377     RequestSender* sender,
    378     const DriveApiUrlGenerator& url_generator,
    379     const EntryActionCallback& callback)
    380     : EntryActionRequest(sender, callback),
    381       url_generator_(url_generator) {
    382   DCHECK(!callback.is_null());
    383 }
    384 
    385 FilesDeleteRequest::~FilesDeleteRequest() {}
    386 
    387 net::URLFetcher::RequestType FilesDeleteRequest::GetRequestType() const {
    388   return net::URLFetcher::DELETE_REQUEST;
    389 }
    390 
    391 GURL FilesDeleteRequest::GetURL() const {
    392   return url_generator_.GetFilesDeleteUrl(file_id_);
    393 }
    394 
    395 std::vector<std::string> FilesDeleteRequest::GetExtraRequestHeaders() const {
    396   std::vector<std::string> headers(
    397       EntryActionRequest::GetExtraRequestHeaders());
    398   headers.push_back(util::GenerateIfMatchHeader(etag_));
    399   return headers;
    400 }
    401 
    402 //============================ FilesTrashRequest =============================
    403 
    404 FilesTrashRequest::FilesTrashRequest(
    405     RequestSender* sender,
    406     const DriveApiUrlGenerator& url_generator,
    407     const FileResourceCallback& callback)
    408     : DriveApiDataRequest(
    409           sender,
    410           base::Bind(&ParseJsonAndRun<FileResource>, callback)),
    411       url_generator_(url_generator) {
    412   DCHECK(!callback.is_null());
    413 }
    414 
    415 FilesTrashRequest::~FilesTrashRequest() {}
    416 
    417 net::URLFetcher::RequestType FilesTrashRequest::GetRequestType() const {
    418   return net::URLFetcher::POST;
    419 }
    420 
    421 GURL FilesTrashRequest::GetURLInternal() const {
    422   return url_generator_.GetFilesTrashUrl(file_id_);
    423 }
    424 
    425 //============================== AboutGetRequest =============================
    426 
    427 AboutGetRequest::AboutGetRequest(
    428     RequestSender* sender,
    429     const DriveApiUrlGenerator& url_generator,
    430     const AboutResourceCallback& callback)
    431     : DriveApiDataRequest(
    432           sender,
    433           base::Bind(&ParseJsonAndRun<AboutResource>, callback)),
    434       url_generator_(url_generator) {
    435   DCHECK(!callback.is_null());
    436 }
    437 
    438 AboutGetRequest::~AboutGetRequest() {}
    439 
    440 GURL AboutGetRequest::GetURLInternal() const {
    441   return url_generator_.GetAboutGetUrl();
    442 }
    443 
    444 //============================ ChangesListRequest ===========================
    445 
    446 ChangesListRequest::ChangesListRequest(
    447     RequestSender* sender,
    448     const DriveApiUrlGenerator& url_generator,
    449     const ChangeListCallback& callback)
    450     : DriveApiDataRequest(
    451           sender,
    452           base::Bind(&ParseJsonOnBlockingPoolAndRun<ChangeList>,
    453                      make_scoped_refptr(sender->blocking_task_runner()),
    454                      callback)),
    455       url_generator_(url_generator),
    456       include_deleted_(true),
    457       max_results_(100),
    458       start_change_id_(0) {
    459   DCHECK(!callback.is_null());
    460 }
    461 
    462 ChangesListRequest::~ChangesListRequest() {}
    463 
    464 GURL ChangesListRequest::GetURLInternal() const {
    465   return url_generator_.GetChangesListUrl(
    466       include_deleted_, max_results_, page_token_, start_change_id_);
    467 }
    468 
    469 //======================== ChangesListNextPageRequest =========================
    470 
    471 ChangesListNextPageRequest::ChangesListNextPageRequest(
    472     RequestSender* sender,
    473     const ChangeListCallback& callback)
    474     : DriveApiDataRequest(
    475           sender,
    476           base::Bind(&ParseJsonOnBlockingPoolAndRun<ChangeList>,
    477                      make_scoped_refptr(sender->blocking_task_runner()),
    478                      callback)) {
    479   DCHECK(!callback.is_null());
    480 }
    481 
    482 ChangesListNextPageRequest::~ChangesListNextPageRequest() {
    483 }
    484 
    485 GURL ChangesListNextPageRequest::GetURLInternal() const {
    486   return next_link_;
    487 }
    488 
    489 //============================== AppsListRequest ===========================
    490 
    491 AppsListRequest::AppsListRequest(
    492     RequestSender* sender,
    493     const DriveApiUrlGenerator& url_generator,
    494     const AppListCallback& callback)
    495     : DriveApiDataRequest(
    496           sender,
    497           base::Bind(&ParseJsonAndRun<AppList>, callback)),
    498       url_generator_(url_generator) {
    499   DCHECK(!callback.is_null());
    500 }
    501 
    502 AppsListRequest::~AppsListRequest() {}
    503 
    504 GURL AppsListRequest::GetURLInternal() const {
    505   return url_generator_.GetAppsListUrl();
    506 }
    507 
    508 //========================== ChildrenInsertRequest ============================
    509 
    510 ChildrenInsertRequest::ChildrenInsertRequest(
    511     RequestSender* sender,
    512     const DriveApiUrlGenerator& url_generator,
    513     const EntryActionCallback& callback)
    514     : EntryActionRequest(sender, callback),
    515       url_generator_(url_generator) {
    516   DCHECK(!callback.is_null());
    517 }
    518 
    519 ChildrenInsertRequest::~ChildrenInsertRequest() {}
    520 
    521 net::URLFetcher::RequestType ChildrenInsertRequest::GetRequestType() const {
    522   return net::URLFetcher::POST;
    523 }
    524 
    525 GURL ChildrenInsertRequest::GetURL() const {
    526   return url_generator_.GetChildrenInsertUrl(folder_id_);
    527 }
    528 
    529 bool ChildrenInsertRequest::GetContentData(std::string* upload_content_type,
    530                                            std::string* upload_content) {
    531   *upload_content_type = kContentTypeApplicationJson;
    532 
    533   base::DictionaryValue root;
    534   root.SetString("id", id_);
    535 
    536   base::JSONWriter::Write(&root, upload_content);
    537   DVLOG(1) << "InsertResource data: " << *upload_content_type << ", ["
    538            << *upload_content << "]";
    539   return true;
    540 }
    541 
    542 //========================== ChildrenDeleteRequest ============================
    543 
    544 ChildrenDeleteRequest::ChildrenDeleteRequest(
    545     RequestSender* sender,
    546     const DriveApiUrlGenerator& url_generator,
    547     const EntryActionCallback& callback)
    548     : EntryActionRequest(sender, callback),
    549       url_generator_(url_generator) {
    550   DCHECK(!callback.is_null());
    551 }
    552 
    553 ChildrenDeleteRequest::~ChildrenDeleteRequest() {}
    554 
    555 net::URLFetcher::RequestType ChildrenDeleteRequest::GetRequestType() const {
    556   return net::URLFetcher::DELETE_REQUEST;
    557 }
    558 
    559 GURL ChildrenDeleteRequest::GetURL() const {
    560   return url_generator_.GetChildrenDeleteUrl(child_id_, folder_id_);
    561 }
    562 
    563 //======================= InitiateUploadNewFileRequest =======================
    564 
    565 InitiateUploadNewFileRequest::InitiateUploadNewFileRequest(
    566     RequestSender* sender,
    567     const DriveApiUrlGenerator& url_generator,
    568     const std::string& content_type,
    569     int64 content_length,
    570     const std::string& parent_resource_id,
    571     const std::string& title,
    572     const InitiateUploadCallback& callback)
    573     : InitiateUploadRequestBase(sender,
    574                                 callback,
    575                                 content_type,
    576                                 content_length),
    577       url_generator_(url_generator),
    578       parent_resource_id_(parent_resource_id),
    579       title_(title) {
    580 }
    581 
    582 InitiateUploadNewFileRequest::~InitiateUploadNewFileRequest() {}
    583 
    584 GURL InitiateUploadNewFileRequest::GetURL() const {
    585   return url_generator_.GetInitiateUploadNewFileUrl();
    586 }
    587 
    588 net::URLFetcher::RequestType
    589 InitiateUploadNewFileRequest::GetRequestType() const {
    590   return net::URLFetcher::POST;
    591 }
    592 
    593 bool InitiateUploadNewFileRequest::GetContentData(
    594     std::string* upload_content_type,
    595     std::string* upload_content) {
    596   *upload_content_type = kContentTypeApplicationJson;
    597 
    598   base::DictionaryValue root;
    599   root.SetString("title", title_);
    600 
    601   // Fill parent link.
    602   {
    603     scoped_ptr<base::DictionaryValue> parent(new base::DictionaryValue);
    604     parent->SetString("kind", kParentLinkKind);
    605     parent->SetString("id", parent_resource_id_);
    606 
    607     scoped_ptr<base::ListValue> parents(new base::ListValue);
    608     parents->Append(parent.release());
    609 
    610     root.Set("parents", parents.release());
    611   }
    612 
    613   base::JSONWriter::Write(&root, upload_content);
    614 
    615   DVLOG(1) << "InitiateUploadNewFile data: " << *upload_content_type << ", ["
    616            << *upload_content << "]";
    617   return true;
    618 }
    619 
    620 //===================== InitiateUploadExistingFileRequest ====================
    621 
    622 InitiateUploadExistingFileRequest::InitiateUploadExistingFileRequest(
    623     RequestSender* sender,
    624     const DriveApiUrlGenerator& url_generator,
    625     const std::string& content_type,
    626     int64 content_length,
    627     const std::string& resource_id,
    628     const std::string& etag,
    629     const InitiateUploadCallback& callback)
    630     : InitiateUploadRequestBase(sender,
    631                                 callback,
    632                                 content_type,
    633                                 content_length),
    634       url_generator_(url_generator),
    635       resource_id_(resource_id),
    636       etag_(etag) {
    637 }
    638 
    639 InitiateUploadExistingFileRequest::~InitiateUploadExistingFileRequest() {}
    640 
    641 GURL InitiateUploadExistingFileRequest::GetURL() const {
    642   return url_generator_.GetInitiateUploadExistingFileUrl(resource_id_);
    643 }
    644 
    645 net::URLFetcher::RequestType
    646 InitiateUploadExistingFileRequest::GetRequestType() const {
    647   return net::URLFetcher::PUT;
    648 }
    649 
    650 std::vector<std::string>
    651 InitiateUploadExistingFileRequest::GetExtraRequestHeaders() const {
    652   std::vector<std::string> headers(
    653       InitiateUploadRequestBase::GetExtraRequestHeaders());
    654   headers.push_back(util::GenerateIfMatchHeader(etag_));
    655   return headers;
    656 }
    657 
    658 //============================ ResumeUploadRequest ===========================
    659 
    660 ResumeUploadRequest::ResumeUploadRequest(
    661     RequestSender* sender,
    662     const GURL& upload_location,
    663     int64 start_position,
    664     int64 end_position,
    665     int64 content_length,
    666     const std::string& content_type,
    667     const base::FilePath& local_file_path,
    668     const UploadRangeCallback& callback,
    669     const ProgressCallback& progress_callback)
    670     : ResumeUploadRequestBase(sender,
    671                               upload_location,
    672                               start_position,
    673                               end_position,
    674                               content_length,
    675                               content_type,
    676                               local_file_path),
    677       callback_(callback),
    678       progress_callback_(progress_callback) {
    679   DCHECK(!callback_.is_null());
    680 }
    681 
    682 ResumeUploadRequest::~ResumeUploadRequest() {}
    683 
    684 void ResumeUploadRequest::OnRangeRequestComplete(
    685     const UploadRangeResponse& response,
    686     scoped_ptr<base::Value> value) {
    687   DCHECK(CalledOnValidThread());
    688   ParseFileResourceWithUploadRangeAndRun(callback_, response, value.Pass());
    689 }
    690 
    691 void ResumeUploadRequest::OnURLFetchUploadProgress(
    692     const net::URLFetcher* source, int64 current, int64 total) {
    693   if (!progress_callback_.is_null())
    694     progress_callback_.Run(current, total);
    695 }
    696 
    697 //========================== GetUploadStatusRequest ==========================
    698 
    699 GetUploadStatusRequest::GetUploadStatusRequest(
    700     RequestSender* sender,
    701     const GURL& upload_url,
    702     int64 content_length,
    703     const UploadRangeCallback& callback)
    704     : GetUploadStatusRequestBase(sender,
    705                                  upload_url,
    706                                  content_length),
    707       callback_(callback) {
    708   DCHECK(!callback.is_null());
    709 }
    710 
    711 GetUploadStatusRequest::~GetUploadStatusRequest() {}
    712 
    713 void GetUploadStatusRequest::OnRangeRequestComplete(
    714     const UploadRangeResponse& response,
    715     scoped_ptr<base::Value> value) {
    716   DCHECK(CalledOnValidThread());
    717   ParseFileResourceWithUploadRangeAndRun(callback_, response, value.Pass());
    718 }
    719 
    720 //========================== DownloadFileRequest ==========================
    721 
    722 DownloadFileRequest::DownloadFileRequest(
    723     RequestSender* sender,
    724     const DriveApiUrlGenerator& url_generator,
    725     const std::string& resource_id,
    726     const base::FilePath& output_file_path,
    727     const DownloadActionCallback& download_action_callback,
    728     const GetContentCallback& get_content_callback,
    729     const ProgressCallback& progress_callback)
    730     : DownloadFileRequestBase(
    731           sender,
    732           download_action_callback,
    733           get_content_callback,
    734           progress_callback,
    735           url_generator.GenerateDownloadFileUrl(resource_id),
    736           output_file_path) {
    737 }
    738 
    739 DownloadFileRequest::~DownloadFileRequest() {
    740 }
    741 
    742 }  // namespace drive
    743 }  // namespace google_apis
    744