Drive: Add definition of StartBatchRequest to DriveServiceInterface.
[chromium-blink-merge.git] / chrome / browser / drive / drive_api_service.cc
blob7a19b851359f1e511061c8152b2fdead5d2d8cd3
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.
5 #include "chrome/browser/drive/drive_api_service.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/drive/drive_api_util.h"
13 #include "google_apis/drive/auth_service.h"
14 #include "google_apis/drive/drive_api_parser.h"
15 #include "google_apis/drive/drive_api_requests.h"
16 #include "google_apis/drive/request_sender.h"
17 #include "google_apis/google_api_keys.h"
18 #include "net/url_request/url_request_context_getter.h"
20 using google_apis::AboutResourceCallback;
21 using google_apis::AppList;
22 using google_apis::AppListCallback;
23 using google_apis::AuthStatusCallback;
24 using google_apis::AuthorizeAppCallback;
25 using google_apis::CancelCallback;
26 using google_apis::ChangeList;
27 using google_apis::ChangeListCallback;
28 using google_apis::DownloadActionCallback;
29 using google_apis::EntryActionCallback;
30 using google_apis::FileList;
31 using google_apis::FileListCallback;
32 using google_apis::FileResource;
33 using google_apis::FileResourceCallback;
34 using google_apis::DRIVE_OTHER_ERROR;
35 using google_apis::DRIVE_PARSE_ERROR;
36 using google_apis::DriveApiErrorCode;
37 using google_apis::GetContentCallback;
38 using google_apis::GetShareUrlCallback;
39 using google_apis::HTTP_NOT_IMPLEMENTED;
40 using google_apis::HTTP_SUCCESS;
41 using google_apis::InitiateUploadCallback;
42 using google_apis::ProgressCallback;
43 using google_apis::RequestSender;
44 using google_apis::UploadRangeResponse;
45 using google_apis::drive::AboutGetRequest;
46 using google_apis::drive::AppsListRequest;
47 using google_apis::drive::ChangesListRequest;
48 using google_apis::drive::ChangesListNextPageRequest;
49 using google_apis::drive::ChildrenDeleteRequest;
50 using google_apis::drive::ChildrenInsertRequest;
51 using google_apis::drive::DownloadFileRequest;
52 using google_apis::drive::FilesCopyRequest;
53 using google_apis::drive::FilesGetRequest;
54 using google_apis::drive::FilesInsertRequest;
55 using google_apis::drive::FilesPatchRequest;
56 using google_apis::drive::FilesListRequest;
57 using google_apis::drive::FilesListNextPageRequest;
58 using google_apis::drive::FilesDeleteRequest;
59 using google_apis::drive::FilesTrashRequest;
60 using google_apis::drive::GetUploadStatusRequest;
61 using google_apis::drive::InitiateUploadExistingFileRequest;
62 using google_apis::drive::InitiateUploadNewFileRequest;
63 using google_apis::drive::ResumeUploadRequest;
64 using google_apis::drive::UploadRangeCallback;
66 namespace drive {
68 namespace {
70 // OAuth2 scopes for Drive API.
71 const char kDriveScope[] = "https://www.googleapis.com/auth/drive";
72 const char kDriveAppsReadonlyScope[] =
73 "https://www.googleapis.com/auth/drive.apps.readonly";
74 const char kDriveAppsScope[] = "https://www.googleapis.com/auth/drive.apps";
75 const char kDocsListScope[] = "https://docs.google.com/feeds/";
77 // Mime type to create a directory.
78 const char kFolderMimeType[] = "application/vnd.google-apps.folder";
80 // Max number of file entries to be fetched in a single http request.
82 // The larger the number is,
83 // - The total running time to fetch the whole file list will become shorter.
84 // - The running time for a single request tends to become longer.
85 // Since the file list fetching is a completely background task, for our side,
86 // only the total time matters. However, the server seems to have a time limit
87 // per single request, which disables us to set the largest value (1000).
88 // TODO(kinaba): make it larger when the server gets faster.
89 const int kMaxNumFilesResourcePerRequest = 300;
90 const int kMaxNumFilesResourcePerRequestForSearch = 100;
92 // For performance, we declare all fields we use.
93 const char kAboutResourceFields[] =
94 "kind,quotaBytesTotal,quotaBytesUsed,largestChangeId,rootFolderId";
95 const char kFileResourceFields[] =
96 "kind,id,title,createdDate,sharedWithMeDate,mimeType,"
97 "md5Checksum,fileSize,labels/trashed,imageMediaMetadata/width,"
98 "imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
99 "parents(id,parentLink),alternateLink,"
100 "modifiedDate,lastViewedByMeDate,shared";
101 const char kFileResourceOpenWithLinksFields[] =
102 "kind,id,openWithLinks/*";
103 const char kFileResourceShareLinkFields[] =
104 "kind,id,shareLink";
105 const char kFileListFields[] =
106 "kind,items(kind,id,title,createdDate,sharedWithMeDate,"
107 "mimeType,md5Checksum,fileSize,labels/trashed,imageMediaMetadata/width,"
108 "imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
109 "parents(id,parentLink),alternateLink,"
110 "modifiedDate,lastViewedByMeDate,shared),nextLink";
111 const char kChangeListFields[] =
112 "kind,items(file(kind,id,title,createdDate,sharedWithMeDate,"
113 "mimeType,md5Checksum,fileSize,labels/trashed,imageMediaMetadata/width,"
114 "imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
115 "parents(id,parentLink),alternateLink,modifiedDate,"
116 "lastViewedByMeDate,shared),deleted,id,fileId,modificationDate),nextLink,"
117 "largestChangeId";
119 void ExtractOpenUrlAndRun(const std::string& app_id,
120 const AuthorizeAppCallback& callback,
121 DriveApiErrorCode error,
122 scoped_ptr<FileResource> value) {
123 DCHECK(!callback.is_null());
125 if (!value) {
126 callback.Run(error, GURL());
127 return;
130 const std::vector<FileResource::OpenWithLink>& open_with_links =
131 value->open_with_links();
132 for (size_t i = 0; i < open_with_links.size(); ++i) {
133 if (open_with_links[i].app_id == app_id) {
134 callback.Run(HTTP_SUCCESS, open_with_links[i].open_url);
135 return;
139 // Not found.
140 callback.Run(DRIVE_OTHER_ERROR, GURL());
143 void ExtractShareUrlAndRun(const GetShareUrlCallback& callback,
144 DriveApiErrorCode error,
145 scoped_ptr<FileResource> value) {
146 callback.Run(error, value ? value->share_link() : GURL());
149 // Ignores the |entry|, and runs the |callback|.
150 void EntryActionCallbackAdapter(
151 const EntryActionCallback& callback,
152 DriveApiErrorCode error, scoped_ptr<FileResource> entry) {
153 callback.Run(error);
156 // The resource ID for the root directory for Drive API is defined in the spec:
157 // https://developers.google.com/drive/folder
158 const char kDriveApiRootDirectoryResourceId[] = "root";
160 } // namespace
162 BatchRequestConfigurator::BatchRequestConfigurator() {
165 BatchRequestConfigurator::~BatchRequestConfigurator() {
168 google_apis::CancelCallback BatchRequestConfigurator::MultipartUploadNewFile(
169 const std::string& content_type,
170 int64 content_length,
171 const std::string& parent_resource_id,
172 const std::string& title,
173 const base::FilePath& local_file_path,
174 const UploadNewFileOptions& options,
175 const google_apis::FileResourceCallback& callback,
176 const google_apis::ProgressCallback& progress_callback) {
177 DCHECK(CalledOnValidThread());
178 DCHECK(!callback.is_null());
180 NOTIMPLEMENTED();
182 return google_apis::CancelCallback();
185 google_apis::CancelCallback
186 BatchRequestConfigurator::MultipartUploadExistingFile(
187 const std::string& content_type,
188 int64 content_length,
189 const std::string& resource_id,
190 const base::FilePath& local_file_path,
191 const UploadExistingFileOptions& options,
192 const google_apis::FileResourceCallback& callback,
193 const google_apis::ProgressCallback& progress_callback) {
194 DCHECK(CalledOnValidThread());
195 DCHECK(!callback.is_null());
197 NOTIMPLEMENTED();
199 return google_apis::CancelCallback();
202 void BatchRequestConfigurator::Commit() {
203 DCHECK(CalledOnValidThread());
204 NOTIMPLEMENTED();
207 DriveAPIService::DriveAPIService(
208 OAuth2TokenService* oauth2_token_service,
209 net::URLRequestContextGetter* url_request_context_getter,
210 base::SequencedTaskRunner* blocking_task_runner,
211 const GURL& base_url,
212 const GURL& base_download_url,
213 const std::string& custom_user_agent)
214 : oauth2_token_service_(oauth2_token_service),
215 url_request_context_getter_(url_request_context_getter),
216 blocking_task_runner_(blocking_task_runner),
217 url_generator_(base_url, base_download_url),
218 custom_user_agent_(custom_user_agent) {
221 DriveAPIService::~DriveAPIService() {
222 DCHECK(thread_checker_.CalledOnValidThread());
223 if (sender_.get())
224 sender_->auth_service()->RemoveObserver(this);
227 void DriveAPIService::Initialize(const std::string& account_id) {
228 DCHECK(thread_checker_.CalledOnValidThread());
230 std::vector<std::string> scopes;
231 scopes.push_back(kDriveScope);
232 scopes.push_back(kDriveAppsReadonlyScope);
233 scopes.push_back(kDriveAppsScope);
235 // Note: The following scope is used to support GetShareUrl on Drive API v2.
236 // Unfortunately, there is no support on Drive API v2, so we need to fall back
237 // to GData WAPI for the GetShareUrl.
238 scopes.push_back(kDocsListScope);
240 sender_.reset(new RequestSender(
241 new google_apis::AuthService(oauth2_token_service_,
242 account_id,
243 url_request_context_getter_.get(),
244 scopes),
245 url_request_context_getter_.get(),
246 blocking_task_runner_.get(),
247 custom_user_agent_));
248 sender_->auth_service()->AddObserver(this);
251 void DriveAPIService::AddObserver(DriveServiceObserver* observer) {
252 observers_.AddObserver(observer);
255 void DriveAPIService::RemoveObserver(DriveServiceObserver* observer) {
256 observers_.RemoveObserver(observer);
259 bool DriveAPIService::CanSendRequest() const {
260 DCHECK(thread_checker_.CalledOnValidThread());
262 return HasRefreshToken();
265 std::string DriveAPIService::GetRootResourceId() const {
266 return kDriveApiRootDirectoryResourceId;
269 CancelCallback DriveAPIService::GetAllFileList(
270 const FileListCallback& callback) {
271 DCHECK(thread_checker_.CalledOnValidThread());
272 DCHECK(!callback.is_null());
274 FilesListRequest* request = new FilesListRequest(
275 sender_.get(), url_generator_, callback);
276 request->set_max_results(kMaxNumFilesResourcePerRequest);
277 request->set_q("trashed = false"); // Exclude trashed files.
278 request->set_fields(kFileListFields);
279 return sender_->StartRequestWithRetry(request);
282 CancelCallback DriveAPIService::GetFileListInDirectory(
283 const std::string& directory_resource_id,
284 const FileListCallback& callback) {
285 DCHECK(thread_checker_.CalledOnValidThread());
286 DCHECK(!directory_resource_id.empty());
287 DCHECK(!callback.is_null());
289 // Because children.list method on Drive API v2 returns only the list of
290 // children's references, but we need all file resource list.
291 // So, here we use files.list method instead, with setting parents query.
292 // After the migration from GData WAPI to Drive API v2, we should clean the
293 // code up by moving the responsibility to include "parents" in the query
294 // to client side.
295 // We aren't interested in files in trash in this context, neither.
296 FilesListRequest* request = new FilesListRequest(
297 sender_.get(), url_generator_, callback);
298 request->set_max_results(kMaxNumFilesResourcePerRequest);
299 request->set_q(base::StringPrintf(
300 "'%s' in parents and trashed = false",
301 util::EscapeQueryStringValue(directory_resource_id).c_str()));
302 request->set_fields(kFileListFields);
303 return sender_->StartRequestWithRetry(request);
306 CancelCallback DriveAPIService::Search(
307 const std::string& search_query,
308 const FileListCallback& callback) {
309 DCHECK(thread_checker_.CalledOnValidThread());
310 DCHECK(!search_query.empty());
311 DCHECK(!callback.is_null());
313 FilesListRequest* request = new FilesListRequest(
314 sender_.get(), url_generator_, callback);
315 request->set_max_results(kMaxNumFilesResourcePerRequestForSearch);
316 request->set_q(util::TranslateQuery(search_query));
317 request->set_fields(kFileListFields);
318 return sender_->StartRequestWithRetry(request);
321 CancelCallback DriveAPIService::SearchByTitle(
322 const std::string& title,
323 const std::string& directory_resource_id,
324 const FileListCallback& callback) {
325 DCHECK(thread_checker_.CalledOnValidThread());
326 DCHECK(!title.empty());
327 DCHECK(!callback.is_null());
329 std::string query;
330 base::StringAppendF(&query, "title = '%s'",
331 util::EscapeQueryStringValue(title).c_str());
332 if (!directory_resource_id.empty()) {
333 base::StringAppendF(
334 &query, " and '%s' in parents",
335 util::EscapeQueryStringValue(directory_resource_id).c_str());
337 query += " and trashed = false";
339 FilesListRequest* request = new FilesListRequest(
340 sender_.get(), url_generator_, callback);
341 request->set_max_results(kMaxNumFilesResourcePerRequest);
342 request->set_q(query);
343 request->set_fields(kFileListFields);
344 return sender_->StartRequestWithRetry(request);
347 CancelCallback DriveAPIService::GetChangeList(
348 int64 start_changestamp,
349 const ChangeListCallback& callback) {
350 DCHECK(thread_checker_.CalledOnValidThread());
351 DCHECK(!callback.is_null());
353 ChangesListRequest* request = new ChangesListRequest(
354 sender_.get(), url_generator_, callback);
355 request->set_max_results(kMaxNumFilesResourcePerRequest);
356 request->set_start_change_id(start_changestamp);
357 request->set_fields(kChangeListFields);
358 return sender_->StartRequestWithRetry(request);
361 CancelCallback DriveAPIService::GetRemainingChangeList(
362 const GURL& next_link,
363 const ChangeListCallback& callback) {
364 DCHECK(thread_checker_.CalledOnValidThread());
365 DCHECK(!next_link.is_empty());
366 DCHECK(!callback.is_null());
368 ChangesListNextPageRequest* request = new ChangesListNextPageRequest(
369 sender_.get(), callback);
370 request->set_next_link(next_link);
371 request->set_fields(kChangeListFields);
372 return sender_->StartRequestWithRetry(request);
375 CancelCallback DriveAPIService::GetRemainingFileList(
376 const GURL& next_link,
377 const FileListCallback& callback) {
378 DCHECK(thread_checker_.CalledOnValidThread());
379 DCHECK(!next_link.is_empty());
380 DCHECK(!callback.is_null());
382 FilesListNextPageRequest* request = new FilesListNextPageRequest(
383 sender_.get(), callback);
384 request->set_next_link(next_link);
385 request->set_fields(kFileListFields);
386 return sender_->StartRequestWithRetry(request);
389 CancelCallback DriveAPIService::GetFileResource(
390 const std::string& resource_id,
391 const FileResourceCallback& callback) {
392 DCHECK(thread_checker_.CalledOnValidThread());
393 DCHECK(!callback.is_null());
395 FilesGetRequest* request = new FilesGetRequest(
396 sender_.get(), url_generator_, google_apis::IsGoogleChromeAPIKeyUsed(),
397 callback);
398 request->set_file_id(resource_id);
399 request->set_fields(kFileResourceFields);
400 return sender_->StartRequestWithRetry(request);
403 CancelCallback DriveAPIService::GetShareUrl(
404 const std::string& resource_id,
405 const GURL& embed_origin,
406 const GetShareUrlCallback& callback) {
407 DCHECK(thread_checker_.CalledOnValidThread());
408 DCHECK(!callback.is_null());
410 if (!google_apis::IsGoogleChromeAPIKeyUsed()) {
411 LOG(ERROR) << "Only the official build of Chrome OS can open share dialogs "
412 << "from the file manager.";
415 FilesGetRequest* request = new FilesGetRequest(
416 sender_.get(), url_generator_, google_apis::IsGoogleChromeAPIKeyUsed(),
417 base::Bind(&ExtractShareUrlAndRun, callback));
418 request->set_file_id(resource_id);
419 request->set_fields(kFileResourceShareLinkFields);
420 request->set_embed_origin(embed_origin);
421 return sender_->StartRequestWithRetry(request);
424 CancelCallback DriveAPIService::GetAboutResource(
425 const AboutResourceCallback& callback) {
426 DCHECK(thread_checker_.CalledOnValidThread());
427 DCHECK(!callback.is_null());
429 AboutGetRequest* request =
430 new AboutGetRequest(sender_.get(), url_generator_, callback);
431 request->set_fields(kAboutResourceFields);
432 return sender_->StartRequestWithRetry(request);
435 CancelCallback DriveAPIService::GetAppList(const AppListCallback& callback) {
436 DCHECK(thread_checker_.CalledOnValidThread());
437 DCHECK(!callback.is_null());
439 return sender_->StartRequestWithRetry(
440 new AppsListRequest(sender_.get(), url_generator_,
441 google_apis::IsGoogleChromeAPIKeyUsed(),
442 callback));
445 CancelCallback DriveAPIService::DownloadFile(
446 const base::FilePath& local_cache_path,
447 const std::string& resource_id,
448 const DownloadActionCallback& download_action_callback,
449 const GetContentCallback& get_content_callback,
450 const ProgressCallback& progress_callback) {
451 DCHECK(thread_checker_.CalledOnValidThread());
452 DCHECK(!download_action_callback.is_null());
453 // get_content_callback may be null.
455 return sender_->StartRequestWithRetry(
456 new DownloadFileRequest(sender_.get(),
457 url_generator_,
458 resource_id,
459 local_cache_path,
460 download_action_callback,
461 get_content_callback,
462 progress_callback));
465 CancelCallback DriveAPIService::DeleteResource(
466 const std::string& resource_id,
467 const std::string& etag,
468 const EntryActionCallback& callback) {
469 DCHECK(thread_checker_.CalledOnValidThread());
470 DCHECK(!callback.is_null());
472 FilesDeleteRequest* request = new FilesDeleteRequest(
473 sender_.get(), url_generator_, callback);
474 request->set_file_id(resource_id);
475 request->set_etag(etag);
476 return sender_->StartRequestWithRetry(request);
479 CancelCallback DriveAPIService::TrashResource(
480 const std::string& resource_id,
481 const EntryActionCallback& callback) {
482 DCHECK(thread_checker_.CalledOnValidThread());
483 DCHECK(!callback.is_null());
485 FilesTrashRequest* request = new FilesTrashRequest(
486 sender_.get(), url_generator_,
487 base::Bind(&EntryActionCallbackAdapter, callback));
488 request->set_file_id(resource_id);
489 request->set_fields(kFileResourceFields);
490 return sender_->StartRequestWithRetry(request);
493 CancelCallback DriveAPIService::AddNewDirectory(
494 const std::string& parent_resource_id,
495 const std::string& directory_title,
496 const AddNewDirectoryOptions& options,
497 const FileResourceCallback& callback) {
498 DCHECK(thread_checker_.CalledOnValidThread());
499 DCHECK(!callback.is_null());
501 FilesInsertRequest* request = new FilesInsertRequest(
502 sender_.get(), url_generator_, callback);
503 request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
504 request->set_mime_type(kFolderMimeType);
505 request->set_modified_date(options.modified_date);
506 request->add_parent(parent_resource_id);
507 request->set_title(directory_title);
508 request->set_properties(options.properties);
509 request->set_fields(kFileResourceFields);
510 return sender_->StartRequestWithRetry(request);
513 CancelCallback DriveAPIService::CopyResource(
514 const std::string& resource_id,
515 const std::string& parent_resource_id,
516 const std::string& new_title,
517 const base::Time& last_modified,
518 const FileResourceCallback& callback) {
519 DCHECK(thread_checker_.CalledOnValidThread());
520 DCHECK(!callback.is_null());
522 FilesCopyRequest* request = new FilesCopyRequest(
523 sender_.get(), url_generator_, callback);
524 request->set_file_id(resource_id);
525 request->add_parent(parent_resource_id);
526 request->set_title(new_title);
527 request->set_modified_date(last_modified);
528 request->set_fields(kFileResourceFields);
529 return sender_->StartRequestWithRetry(request);
532 CancelCallback DriveAPIService::UpdateResource(
533 const std::string& resource_id,
534 const std::string& parent_resource_id,
535 const std::string& new_title,
536 const base::Time& last_modified,
537 const base::Time& last_viewed_by_me,
538 const google_apis::drive::Properties& properties,
539 const FileResourceCallback& callback) {
540 DCHECK(thread_checker_.CalledOnValidThread());
541 DCHECK(!callback.is_null());
543 FilesPatchRequest* request = new FilesPatchRequest(
544 sender_.get(), url_generator_, callback);
545 request->set_file_id(resource_id);
546 request->set_title(new_title);
547 if (!parent_resource_id.empty())
548 request->add_parent(parent_resource_id);
549 if (!last_modified.is_null()) {
550 // Need to set setModifiedDate to true to overwrite modifiedDate.
551 request->set_set_modified_date(true);
552 request->set_modified_date(last_modified);
554 if (!last_viewed_by_me.is_null()) {
555 // Need to set updateViewedDate to false, otherwise the lastViewedByMeDate
556 // will be set to the request time (not the specified time via request).
557 request->set_update_viewed_date(false);
558 request->set_last_viewed_by_me_date(last_viewed_by_me);
560 request->set_fields(kFileResourceFields);
561 request->set_properties(properties);
562 return sender_->StartRequestWithRetry(request);
565 CancelCallback DriveAPIService::AddResourceToDirectory(
566 const std::string& parent_resource_id,
567 const std::string& resource_id,
568 const EntryActionCallback& callback) {
569 DCHECK(thread_checker_.CalledOnValidThread());
570 DCHECK(!callback.is_null());
572 ChildrenInsertRequest* request =
573 new ChildrenInsertRequest(sender_.get(), url_generator_, callback);
574 request->set_folder_id(parent_resource_id);
575 request->set_id(resource_id);
576 return sender_->StartRequestWithRetry(request);
579 CancelCallback DriveAPIService::RemoveResourceFromDirectory(
580 const std::string& parent_resource_id,
581 const std::string& resource_id,
582 const EntryActionCallback& callback) {
583 DCHECK(thread_checker_.CalledOnValidThread());
584 DCHECK(!callback.is_null());
586 ChildrenDeleteRequest* request =
587 new ChildrenDeleteRequest(sender_.get(), url_generator_, callback);
588 request->set_child_id(resource_id);
589 request->set_folder_id(parent_resource_id);
590 return sender_->StartRequestWithRetry(request);
593 CancelCallback DriveAPIService::InitiateUploadNewFile(
594 const std::string& content_type,
595 int64 content_length,
596 const std::string& parent_resource_id,
597 const std::string& title,
598 const UploadNewFileOptions& options,
599 const InitiateUploadCallback& callback) {
600 DCHECK(thread_checker_.CalledOnValidThread());
601 DCHECK(!callback.is_null());
603 InitiateUploadNewFileRequest* request =
604 new InitiateUploadNewFileRequest(sender_.get(),
605 url_generator_,
606 content_type,
607 content_length,
608 parent_resource_id,
609 title,
610 callback);
611 request->set_modified_date(options.modified_date);
612 request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
613 request->set_properties(options.properties);
614 return sender_->StartRequestWithRetry(request);
617 CancelCallback DriveAPIService::InitiateUploadExistingFile(
618 const std::string& content_type,
619 int64 content_length,
620 const std::string& resource_id,
621 const UploadExistingFileOptions& options,
622 const InitiateUploadCallback& callback) {
623 DCHECK(thread_checker_.CalledOnValidThread());
624 DCHECK(!callback.is_null());
626 InitiateUploadExistingFileRequest* request =
627 new InitiateUploadExistingFileRequest(sender_.get(),
628 url_generator_,
629 content_type,
630 content_length,
631 resource_id,
632 options.etag,
633 callback);
634 request->set_parent_resource_id(options.parent_resource_id);
635 request->set_title(options.title);
636 request->set_modified_date(options.modified_date);
637 request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
638 request->set_properties(options.properties);
639 return sender_->StartRequestWithRetry(request);
642 CancelCallback DriveAPIService::ResumeUpload(
643 const GURL& upload_url,
644 int64 start_position,
645 int64 end_position,
646 int64 content_length,
647 const std::string& content_type,
648 const base::FilePath& local_file_path,
649 const UploadRangeCallback& callback,
650 const ProgressCallback& progress_callback) {
651 DCHECK(thread_checker_.CalledOnValidThread());
652 DCHECK(!callback.is_null());
654 return sender_->StartRequestWithRetry(
655 new ResumeUploadRequest(
656 sender_.get(),
657 upload_url,
658 start_position,
659 end_position,
660 content_length,
661 content_type,
662 local_file_path,
663 callback,
664 progress_callback));
667 CancelCallback DriveAPIService::GetUploadStatus(
668 const GURL& upload_url,
669 int64 content_length,
670 const UploadRangeCallback& callback) {
671 DCHECK(thread_checker_.CalledOnValidThread());
672 DCHECK(!callback.is_null());
674 return sender_->StartRequestWithRetry(new GetUploadStatusRequest(
675 sender_.get(),
676 upload_url,
677 content_length,
678 callback));
681 CancelCallback DriveAPIService::MultipartUploadNewFile(
682 const std::string& content_type,
683 int64 content_length,
684 const std::string& parent_resource_id,
685 const std::string& title,
686 const base::FilePath& local_file_path,
687 const drive::UploadNewFileOptions& options,
688 const FileResourceCallback& callback,
689 const google_apis::ProgressCallback& progress_callback) {
690 DCHECK(thread_checker_.CalledOnValidThread());
691 DCHECK(!callback.is_null());
693 return sender_->StartRequestWithRetry(
694 new google_apis::drive::MultipartUploadNewFileRequest(
695 sender_.get(), title, parent_resource_id, content_type,
696 content_length, options.modified_date, options.last_viewed_by_me_date,
697 local_file_path, options.properties, url_generator_, callback,
698 progress_callback));
701 CancelCallback DriveAPIService::MultipartUploadExistingFile(
702 const std::string& content_type,
703 int64 content_length,
704 const std::string& resource_id,
705 const base::FilePath& local_file_path,
706 const drive::UploadExistingFileOptions& options,
707 const FileResourceCallback& callback,
708 const google_apis::ProgressCallback& progress_callback) {
709 DCHECK(thread_checker_.CalledOnValidThread());
710 DCHECK(!callback.is_null());
712 return sender_->StartRequestWithRetry(
713 new google_apis::drive::MultipartUploadExistingFileRequest(
714 sender_.get(), options.title, resource_id, options.parent_resource_id,
715 content_type, content_length, options.modified_date,
716 options.last_viewed_by_me_date, local_file_path, options.etag,
717 options.properties, url_generator_, callback, progress_callback));
720 CancelCallback DriveAPIService::AuthorizeApp(
721 const std::string& resource_id,
722 const std::string& app_id,
723 const AuthorizeAppCallback& callback) {
724 DCHECK(thread_checker_.CalledOnValidThread());
725 DCHECK(!callback.is_null());
727 // Files.Authorize is only available for whitelisted clients like official
728 // Google Chrome. In other cases, we fall back to Files.Get that returns the
729 // same value as Files.Authorize without doing authorization. In that case,
730 // the app can open if it was authorized by other means (from whitelisted
731 // clients or drive.google.com web UI.)
732 if (google_apis::IsGoogleChromeAPIKeyUsed()) {
733 google_apis::drive::FilesAuthorizeRequest* request =
734 new google_apis::drive::FilesAuthorizeRequest(
735 sender_.get(), url_generator_,
736 base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
737 request->set_app_id(app_id);
738 request->set_file_id(resource_id);
739 request->set_fields(kFileResourceOpenWithLinksFields);
740 return sender_->StartRequestWithRetry(request);
741 } else {
742 FilesGetRequest* request = new FilesGetRequest(
743 sender_.get(), url_generator_, google_apis::IsGoogleChromeAPIKeyUsed(),
744 base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
745 request->set_file_id(resource_id);
746 request->set_fields(kFileResourceOpenWithLinksFields);
747 return sender_->StartRequestWithRetry(request);
751 CancelCallback DriveAPIService::UninstallApp(
752 const std::string& app_id,
753 const google_apis::EntryActionCallback& callback) {
754 DCHECK(thread_checker_.CalledOnValidThread());
755 DCHECK(!callback.is_null());
757 google_apis::drive::AppsDeleteRequest* request =
758 new google_apis::drive::AppsDeleteRequest(sender_.get(), url_generator_,
759 callback);
760 request->set_app_id(app_id);
761 return sender_->StartRequestWithRetry(request);
764 google_apis::CancelCallback DriveAPIService::AddPermission(
765 const std::string& resource_id,
766 const std::string& email,
767 google_apis::drive::PermissionRole role,
768 const google_apis::EntryActionCallback& callback) {
769 DCHECK(thread_checker_.CalledOnValidThread());
770 DCHECK(!callback.is_null());
772 google_apis::drive::PermissionsInsertRequest* request =
773 new google_apis::drive::PermissionsInsertRequest(sender_.get(),
774 url_generator_,
775 callback);
776 request->set_id(resource_id);
777 request->set_role(role);
778 request->set_type(google_apis::drive::PERMISSION_TYPE_USER);
779 request->set_value(email);
780 return sender_->StartRequestWithRetry(request);
783 bool DriveAPIService::HasAccessToken() const {
784 DCHECK(thread_checker_.CalledOnValidThread());
785 return sender_->auth_service()->HasAccessToken();
788 void DriveAPIService::RequestAccessToken(const AuthStatusCallback& callback) {
789 DCHECK(thread_checker_.CalledOnValidThread());
790 DCHECK(!callback.is_null());
792 const std::string access_token = sender_->auth_service()->access_token();
793 if (!access_token.empty()) {
794 callback.Run(google_apis::HTTP_NOT_MODIFIED, access_token);
795 return;
798 // Retrieve the new auth token.
799 sender_->auth_service()->StartAuthentication(callback);
802 bool DriveAPIService::HasRefreshToken() const {
803 DCHECK(thread_checker_.CalledOnValidThread());
804 return sender_->auth_service()->HasRefreshToken();
807 void DriveAPIService::ClearAccessToken() {
808 DCHECK(thread_checker_.CalledOnValidThread());
809 sender_->auth_service()->ClearAccessToken();
812 void DriveAPIService::ClearRefreshToken() {
813 DCHECK(thread_checker_.CalledOnValidThread());
814 sender_->auth_service()->ClearRefreshToken();
817 void DriveAPIService::OnOAuth2RefreshTokenChanged() {
818 DCHECK(thread_checker_.CalledOnValidThread());
819 if (CanSendRequest()) {
820 FOR_EACH_OBSERVER(
821 DriveServiceObserver, observers_, OnReadyToSendRequests());
822 } else if (!HasRefreshToken()) {
823 FOR_EACH_OBSERVER(
824 DriveServiceObserver, observers_, OnRefreshTokenInvalid());
828 scoped_ptr<BatchRequestConfiguratorInterface>
829 DriveAPIService::StartBatchRequest() {
830 return make_scoped_ptr<BatchRequestConfiguratorInterface>(
831 new BatchRequestConfigurator);
834 } // namespace drive