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