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"
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
;
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
[] =
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,"
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());
126 callback
.Run(error
, GURL());
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
);
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
) {
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";
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());
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());
199 return google_apis::CancelCallback();
202 void BatchRequestConfigurator::Commit() {
203 DCHECK(CalledOnValidThread());
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());
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_
,
243 url_request_context_getter_
.get(),
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
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());
330 base::StringAppendF(&query
, "title = '%s'",
331 util::EscapeQueryStringValue(title
).c_str());
332 if (!directory_resource_id
.empty()) {
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(),
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(),
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(),
460 download_action_callback
,
461 get_content_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(),
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(),
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
,
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(
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(
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
,
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
);
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_
,
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(),
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
);
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()) {
821 DriveServiceObserver
, observers_
, OnReadyToSendRequests());
822 } else if (!HasRefreshToken()) {
824 DriveServiceObserver
, observers_
, OnRefreshTokenInvalid());
828 scoped_ptr
<BatchRequestConfiguratorInterface
>
829 DriveAPIService::StartBatchRequest() {
830 return make_scoped_ptr
<BatchRequestConfiguratorInterface
>(
831 new BatchRequestConfigurator
);