drive_api_service.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/drive_api_service.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/sequenced_task_runner.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/task_runner_util.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/drive/drive_api_util.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/auth_service.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/drive_api_parser.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/drive_api_requests.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/gdata_errorcode.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/gdata_wapi_parser.h"
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/gdata_wapi_requests.h"
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/request_sender.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/google_api_keys.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AppList;
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::AppListCallback;
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing google_apis::AuthStatusCallback;
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AuthorizeAppCallback;
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback;
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ChangeList;
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::DownloadActionCallback;
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::EntryActionCallback;
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::FileList;
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::FileResource;
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_OTHER_ERROR;
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_PARSE_ERROR;
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDataErrorCode;
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::AboutResourceCallback;
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetContentCallback;
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceEntryCallback;
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using google_apis::GetResourceEntryRequest;
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceListCallback;
46bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing google_apis::GetShareUrlCallback;
47bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing google_apis::HTTP_NOT_IMPLEMENTED;
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS;
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::InitiateUploadCallback;
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using google_apis::Link;
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback;
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::RequestSender;
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceEntry;
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceList;
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeCallback;
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse;
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::AboutGetRequest;
58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::AppsListRequest;
59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::ChangesListRequest;
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using google_apis::drive::ChangesListNextPageRequest;
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using google_apis::drive::ChildrenDeleteRequest;
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using google_apis::drive::ChildrenInsertRequest;
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::DownloadFileRequest;
64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesCopyRequest;
65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesGetRequest;
66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesInsertRequest;
67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesPatchRequest;
68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesListRequest;
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using google_apis::drive::FilesListNextPageRequest;
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using google_apis::drive::FilesDeleteRequest;
71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesTrashRequest;
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::GetUploadStatusRequest;
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InitiateUploadExistingFileRequest;
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InitiateUploadNewFileRequest;
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::ResumeUploadRequest;
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OAuth2 scopes for Drive API.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveScope[] = "https://www.googleapis.com/auth/drive";
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveAppsReadonlyScope[] =
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "https://www.googleapis.com/auth/drive.apps.readonly";
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Mime type to create a directory.
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kFolderMimeType[] = "application/vnd.google-apps.folder";
88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Max number of file entries to be fetched in a single http request.
908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//
918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// The larger the number is,
928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// - The total running time to fetch the whole file list will become shorter.
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// - The running time for a single request tends to become longer.
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Since the file list fetching is a completely background task, for our side,
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// only the total time matters. However, the server seems to have a time limit
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// per single request, which disables us to set the largest value (1000).
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// TODO(kinaba): make it larger when the server gets faster.
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kMaxNumFilesResourcePerRequest = 300;
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kMaxNumFilesResourcePerRequestForSearch = 100;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// For performance, we declare all fields we use.
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kAboutResourceFields[] =
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "kind,quotaBytesTotal,quotaBytesUsed,largestChangeId,rootFolderId";
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kFileResourceFields[] =
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "kind,id,title,createdDate,sharedWithMeDate,mimeType,"
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "md5Checksum,fileSize,labels/trashed,imageMediaMetadata/width,"
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "parents/parentLink,alternateLink,"
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    "modifiedDate,lastViewedByMeDate,shared";
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kFileResourceOpenWithLinksFields[] =
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "kind,id,openWithLinks/*";
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kFileListFields[] =
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "kind,items(kind,id,title,createdDate,sharedWithMeDate,"
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "mimeType,md5Checksum,fileSize,labels/trashed,imageMediaMetadata/width,"
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "parents/parentLink,alternateLink,"
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    "modifiedDate,lastViewedByMeDate,shared),nextLink";
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kChangeListFields[] =
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "kind,items(file(kind,id,title,createdDate,sharedWithMeDate,"
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "mimeType,md5Checksum,fileSize,labels/trashed,imageMediaMetadata/width,"
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "parents/parentLink,alternateLink,modifiedDate,lastViewedByMeDate,shared),"
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "deleted,id,fileId,modificationDate),nextLink,largestChangeId";
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Callback invoked when the parsing of resource list is completed,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// regardless whether it is succeeded or not.
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void DidConvertToResourceListOnBlockingPool(
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback,
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ResourceList> resource_list) {
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = resource_list ? HTTP_SUCCESS : GDATA_PARSE_ERROR;
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.Run(error, resource_list.Pass());
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Converts the FileResource value to ResourceEntry and runs |callback| on the
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// UI thread.
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ConvertFileEntryToResourceEntryAndRun(
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback,
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GDataErrorCode error,
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FileResource> value) {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceEntry>());
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Converting to ResourceEntry is cheap enough to do on UI thread.
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry =
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      util::ConvertFileResourceToResourceEntry(*value);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!entry) {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(GDATA_PARSE_ERROR, scoped_ptr<ResourceEntry>());
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(error, entry.Pass());
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Thin adapter of ConvertFileListToResourceList.
160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)scoped_ptr<ResourceList> ConvertFileListToResourceList(
161424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_ptr<FileList> file_list) {
162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return util::ConvertFileListToResourceList(*file_list);
163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Converts the FileList value to ResourceList on blocking pool and runs
166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// |callback| on the UI thread.
167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ConvertFileListToResourceListOnBlockingPoolAndRun(
168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_refptr<base::TaskRunner> blocking_task_runner,
169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GetResourceListCallback& callback,
170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    GDataErrorCode error,
171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_ptr<FileList> value) {
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceList>());
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Convert the value on blocking pool.
181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      blocking_task_runner.get(),
183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      FROM_HERE,
184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileListToResourceList, base::Passed(&value)),
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&DidConvertToResourceListOnBlockingPool, callback));
186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Thin adapter of ConvertChangeListToResourceList.
189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)scoped_ptr<ResourceList> ConvertChangeListToResourceList(
190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_ptr<ChangeList> change_list) {
191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return util::ConvertChangeListToResourceList(*change_list);
192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Converts the FileList value to ResourceList on blocking pool and runs
195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// |callback| on the UI thread.
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ConvertChangeListToResourceListOnBlockingPoolAndRun(
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_refptr<base::TaskRunner> blocking_task_runner,
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GetResourceListCallback& callback,
199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    GDataErrorCode error,
200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_ptr<ChangeList> value) {
201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!callback.is_null());
203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!value) {
205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceList>());
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Convert the value on blocking pool.
210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      blocking_task_runner.get(),
212424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      FROM_HERE,
213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertChangeListToResourceList, base::Passed(&value)),
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&DidConvertToResourceListOnBlockingPool, callback));
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Converts the FileResource value to ResourceEntry for upload range request,
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and runs |callback| on the UI thread.
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ConvertFileResourceToResourceEntryForUploadRangeAndRun(
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeCallback& callback,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeResponse& response,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FileResource> value) {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(response, scoped_ptr<ResourceEntry>());
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Converting to ResourceEntry is cheap enough to do on UI thread.
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry =
233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      util::ConvertFileResourceToResourceEntry(*value);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!entry) {
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(UploadRangeResponse(GDATA_PARSE_ERROR,
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     response.start_position_received,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     response.end_position_received),
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 scoped_ptr<ResourceEntry>());
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(response, entry.Pass());
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ExtractOpenUrlAndRun(const std::string& app_id,
246a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          const AuthorizeAppCallback& callback,
247a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          GDataErrorCode error,
248a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          scoped_ptr<FileResource> value) {
249a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
250a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(!callback.is_null());
251a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
252a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!value) {
253a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    callback.Run(error, GURL());
254a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
255a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
257a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const std::vector<FileResource::OpenWithLink>& open_with_links =
258a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      value->open_with_links();
259a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  for (size_t i = 0; i < open_with_links.size(); ++i) {
260a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (open_with_links[i].app_id == app_id) {
261a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      callback.Run(HTTP_SUCCESS, open_with_links[i].open_url);
262a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return;
263a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
264a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
265a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
266a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Not found.
267a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  callback.Run(GDATA_OTHER_ERROR, GURL());
268a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
269a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Ignores the |entry|, and runs the |callback|.
2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void EntryActionCallbackAdapter(
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const EntryActionCallback& callback,
2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    GDataErrorCode error, scoped_ptr<FileResource> entry) {
2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  callback.Run(error);
2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The resource ID for the root directory for Drive API is defined in the spec:
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://developers.google.com/drive/folder
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveApiRootDirectoryResourceId[] = "root";
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveAPIService::DriveAPIService(
284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    OAuth2TokenService* oauth2_token_service,
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::URLRequestContextGetter* url_request_context_getter,
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::SequencedTaskRunner* blocking_task_runner,
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& base_url,
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GURL& base_download_url,
289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& wapi_base_url,
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& custom_user_agent)
291558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    : oauth2_token_service_(oauth2_token_service),
292558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      url_request_context_getter_(url_request_context_getter),
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      blocking_task_runner_(blocking_task_runner),
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      url_generator_(base_url, base_download_url),
2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      wapi_url_generator_(wapi_base_url),
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      custom_user_agent_(custom_user_agent) {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveAPIService::~DriveAPIService() {
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (sender_.get())
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    sender_->auth_service()->RemoveObserver(this);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DriveAPIService::Initialize(const std::string& account_id) {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> scopes;
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scopes.push_back(kDriveScope);
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scopes.push_back(kDriveAppsReadonlyScope);
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scopes.push_back(util::kDriveAppsScope);
313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // GData WAPI token for GetShareUrl() and GetResourceListInDirectoryByWapi().
315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scopes.push_back(util::kDocsListScope);
316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  sender_.reset(new RequestSender(
31868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      new google_apis::AuthService(oauth2_token_service_,
31968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                   account_id,
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   url_request_context_getter_.get(),
32168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                   scopes),
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      url_request_context_getter_.get(),
32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      blocking_task_runner_.get(),
32468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      custom_user_agent_));
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sender_->auth_service()->AddObserver(this);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::AddObserver(DriveServiceObserver* observer) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::RemoveObserver(DriveServiceObserver* observer) {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DriveAPIService::CanSendRequest() const {
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return HasRefreshToken();
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)ResourceIdCanonicalizer DriveAPIService::GetResourceIdCanonicalizer() const {
343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return base::Bind(&drive::util::CanonicalizeResourceId);
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DriveAPIService::GetRootResourceId() const {
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kDriveApiRootDirectoryResourceId;
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAllResourceList(
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetResourceListCallback& callback) {
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FilesListRequest* request = new FilesListRequest(
356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequest);
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_q("trashed = false");  // Exclude trashed files.
36168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetResourceListInDirectory(
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& directory_resource_id,
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback) {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!directory_resource_id.empty());
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Because children.list method on Drive API v2 returns only the list of
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // children's references, but we need all file resource list.
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // So, here we use files.list method instead, with setting parents query.
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // After the migration from GData WAPI to Drive API v2, we should clean the
376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // code up by moving the responsibility to include "parents" in the query
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // to client side.
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We aren't interested in files in trash in this context, neither.
379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesListRequest* request = new FilesListRequest(
380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequest);
384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_q(base::StringPrintf(
385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      "'%s' in parents and trashed = false",
386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      drive::util::EscapeQueryStringValue(directory_resource_id).c_str()));
38768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::Search(
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& search_query,
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GetResourceListCallback& callback) {
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!search_query.empty());
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesListRequest* request = new FilesListRequest(
399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequestForSearch);
403424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_q(drive::util::TranslateQuery(search_query));
40468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::SearchByTitle(
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& title,
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& directory_resource_id,
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback) {
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!title.empty());
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string query;
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::StringAppendF(&query, "title = '%s'",
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      drive::util::EscapeQueryStringValue(title).c_str());
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!directory_resource_id.empty()) {
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::StringAppendF(
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &query, " and '%s' in parents",
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        drive::util::EscapeQueryStringValue(directory_resource_id).c_str());
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  query += " and trashed = false";
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
426424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesListRequest* request = new FilesListRequest(
427424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
428424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
429424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
430424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequest);
431424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_q(query);
43268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
433424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetChangeList(
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 start_changestamp,
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GetResourceListCallback& callback) {
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ChangesListRequest* request = new ChangesListRequest(
443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertChangeListToResourceListOnBlockingPoolAndRun,
445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequest);
447424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_start_change_id(start_changestamp);
44868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kChangeListFields);
449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback DriveAPIService::GetRemainingChangeList(
45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& next_link,
454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GetResourceListCallback& callback) {
455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!next_link.is_empty());
457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!callback.is_null());
458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
45958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ChangesListNextPageRequest* request = new ChangesListNextPageRequest(
46058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      sender_.get(),
46158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&ConvertChangeListToResourceListOnBlockingPoolAndRun,
46258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 blocking_task_runner_, callback));
46358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_next_link(next_link);
46468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kChangeListFields);
46558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(request);
466424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
467424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
468424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback DriveAPIService::GetRemainingFileList(
46958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& next_link,
470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GetResourceListCallback& callback) {
471424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
47258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!next_link.is_empty());
473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!callback.is_null());
474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FilesListNextPageRequest* request = new FilesListNextPageRequest(
47658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      sender_.get(),
47758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 blocking_task_runner_, callback));
47958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_next_link(next_link);
48068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(request);
482424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetResourceEntry(
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
490424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesGetRequest* request = new FilesGetRequest(
491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
492424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
49468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
498bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochCancelCallback DriveAPIService::GetShareUrl(
499bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const std::string& resource_id,
500bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const GURL& embed_origin,
501bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const GetShareUrlCallback& callback) {
502bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
503bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(!callback.is_null());
504bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
505a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Unfortunately "share url" is not yet supported on Drive API v2.
506a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // So, as a fallback, we use GData WAPI protocol for this method.
507a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // TODO(hidehiko): Get rid of this implementation when share url is
508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // supported on Drive API v2.
509a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return sender_->StartRequestWithRetry(
510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new GetResourceEntryRequest(sender_.get(),
511a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  wapi_url_generator_,
512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  resource_id,
513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  embed_origin,
514a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  base::Bind(&util::ParseShareUrlAndRun,
515a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                             callback)));
516bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
517bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAboutResource(
519424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const AboutResourceCallback& callback) {
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  AboutGetRequest* request =
52468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      new AboutGetRequest(sender_.get(), url_generator_, callback);
52568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kAboutResourceFields);
52668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
529424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback DriveAPIService::GetAppList(const AppListCallback& callback) {
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
533424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new AppsListRequest(sender_.get(), url_generator_,
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          google_apis::IsGoogleChromeAPIKeyUsed(),
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          callback));
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::DownloadFile(
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& local_cache_path,
541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& resource_id,
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DownloadActionCallback& download_action_callback,
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetContentCallback& get_content_callback,
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_callback) {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!download_action_callback.is_null());
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // get_content_callback may be null.
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new DownloadFileRequest(sender_.get(),
551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              url_generator_,
552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              resource_id,
553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              local_cache_path,
554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              download_action_callback,
555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              get_content_callback,
556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              progress_callback));
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::DeleteResource(
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FilesDeleteRequest* request = new FilesDeleteRequest(
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      sender_.get(), url_generator_, callback);
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_file_id(resource_id);
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_etag(etag);
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CancelCallback DriveAPIService::TrashResource(
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& resource_id,
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const EntryActionCallback& callback) {
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!callback.is_null());
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
579424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesTrashRequest* request = new FilesTrashRequest(
580424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
581424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&EntryActionCallbackAdapter, callback));
582424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
58368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
584424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AddNewDirectory(
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
5897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& directory_title,
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const AddNewDirectoryOptions& options,
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
595424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesInsertRequest* request = new FilesInsertRequest(
596424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
597424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
599424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_mime_type(kFolderMimeType);
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_modified_date(options.modified_date);
601424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->add_parent(parent_resource_id);
602424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_title(directory_title);
60368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
604424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::CopyResource(
60890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
60990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& parent_resource_id,
6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
61168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const base::Time& last_modified,
61290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
61390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
61490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!callback.is_null());
61590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
616424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesCopyRequest* request = new FilesCopyRequest(
617424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
618424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
619424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
620424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->add_parent(parent_resource_id);
621424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_title(new_title);
62268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_modified_date(last_modified);
62368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
624424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
62590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
62690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)CancelCallback DriveAPIService::UpdateResource(
6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& resource_id,
6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& parent_resource_id,
6303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& new_title,
63168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const base::Time& last_modified,
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::Time& last_viewed_by_me,
6333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GetResourceEntryCallback& callback) {
6343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!callback.is_null());
6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
637424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesPatchRequest* request = new FilesPatchRequest(
638424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
639424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
640424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
641424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_title(new_title);
642424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!parent_resource_id.empty())
643424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    request->add_parent(parent_resource_id);
64468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!last_modified.is_null()) {
645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Need to set setModifiedDate to true to overwrite modifiedDate.
64668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request->set_set_modified_date(true);
64768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request->set_modified_date(last_modified);
64868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!last_viewed_by_me.is_null()) {
650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Need to set updateViewedDate to false, otherwise the lastViewedByMeDate
651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // will be set to the request time (not the specified time via request).
652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request->set_update_viewed_date(false);
653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request->set_last_viewed_by_me_date(last_viewed_by_me);
654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
65568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
656424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::RenameResource(
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesPatchRequest* request = new FilesPatchRequest(
667424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
668424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&EntryActionCallbackAdapter, callback));
669424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
670424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_title(new_title);
67168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
672424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AddResourceToDirectory(
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
68258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ChildrenInsertRequest* request =
68358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new ChildrenInsertRequest(sender_.get(), url_generator_, callback);
68458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_folder_id(parent_resource_id);
68558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_id(resource_id);
68658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(request);
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::RemoveResourceFromDirectory(
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
69658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ChildrenDeleteRequest* request =
69758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new ChildrenDeleteRequest(sender_.get(), url_generator_, callback);
69858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_child_id(resource_id);
69958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_folder_id(parent_resource_id);
70058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(request);
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::InitiateUploadNewFile(
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& title,
7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const InitiateUploadNewFileOptions& options,
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitiateUploadNewFileRequest* request =
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new InitiateUploadNewFileRequest(sender_.get(),
7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       url_generator_,
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       content_type,
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       content_length,
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       parent_resource_id,
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       title,
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       callback);
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_modified_date(options.modified_date);
7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::InitiateUploadExistingFile(
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const InitiateUploadExistingFileOptions& options,
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitiateUploadExistingFileRequest* request =
7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new InitiateUploadExistingFileRequest(sender_.get(),
7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            url_generator_,
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            content_type,
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            content_length,
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            resource_id,
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            options.etag,
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            callback);
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_parent_resource_id(options.parent_resource_id);
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_title(options.title);
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_modified_date(options.modified_date);
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::ResumeUpload(
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_url,
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 start_position,
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 end_position,
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
756a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const base::FilePath& local_file_path,
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UploadRangeCallback& callback,
758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_callback) {
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new ResumeUploadRequest(
764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          upload_url,
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          start_position,
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          end_position,
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
770a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          local_file_path,
77158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          base::Bind(&ConvertFileResourceToResourceEntryForUploadRangeAndRun,
77258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     callback),
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          progress_callback));
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetUploadStatus(
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_url,
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeCallback& callback) {
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return sender_->StartRequestWithRetry(new GetUploadStatusRequest(
784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
78590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      upload_url,
78690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content_length,
78758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&ConvertFileResourceToResourceEntryForUploadRangeAndRun,
78858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 callback)));
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AuthorizeApp(
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& app_id,
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AuthorizeAppCallback& callback) {
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Files.Authorize is only available for whitelisted clients like official
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Google Chrome. In other cases, we fall back to Files.Get that returns the
8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // same value as Files.Authorize without doing authorization. In that case,
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the app can open if it was authorized by other means (from whitelisted
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // clients or drive.google.com web UI.)
8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (google_apis::IsGoogleChromeAPIKeyUsed()) {
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    google_apis::drive::FilesAuthorizeRequest* request =
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new google_apis::drive::FilesAuthorizeRequest(
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            sender_.get(), url_generator_,
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    request->set_app_id(app_id);
8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    request->set_file_id(resource_id);
8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    request->set_fields(kFileResourceOpenWithLinksFields);
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return sender_->StartRequestWithRetry(request);
8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FilesGetRequest* request = new FilesGetRequest(
8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        sender_.get(), url_generator_,
8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    request->set_file_id(resource_id);
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    request->set_fields(kFileResourceOpenWithLinksFields);
8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return sender_->StartRequestWithRetry(request);
8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CancelCallback DriveAPIService::UninstallApp(
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& app_id,
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const google_apis::EntryActionCallback& callback) {
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!callback.is_null());
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  google_apis::drive::AppsDeleteRequest* request =
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new google_apis::drive::AppsDeleteRequest(sender_.get(), url_generator_,
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                callback);
8315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request->set_app_id(app_id);
832424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
835a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)google_apis::CancelCallback DriveAPIService::AddPermission(
836a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& resource_id,
837a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& email,
838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    google_apis::drive::PermissionRole role,
839a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const google_apis::EntryActionCallback& callback) {
840a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
841a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!callback.is_null());
842a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  google_apis::drive::PermissionsInsertRequest* request =
844a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new google_apis::drive::PermissionsInsertRequest(sender_.get(),
845a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                       url_generator_,
846a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                       callback);
847a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  request->set_id(resource_id);
848a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  request->set_role(role);
849a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  request->set_type(google_apis::drive::PERMISSION_TYPE_USER);
850a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  request->set_value(email);
851a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
852a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
853a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DriveAPIService::HasAccessToken() const {
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->HasAccessToken();
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DriveAPIService::RequestAccessToken(const AuthStatusCallback& callback) {
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!callback.is_null());
8627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const std::string access_token = sender_->auth_service()->access_token();
8647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!access_token.empty()) {
8657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    callback.Run(google_apis::HTTP_NOT_MODIFIED, access_token);
8667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
8677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
8687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Retrieve the new auth token.
8707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sender_->auth_service()->StartAuthentication(callback);
8717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool DriveAPIService::HasRefreshToken() const {
8747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->HasRefreshToken();
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::ClearAccessToken() {
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sender_->auth_service()->ClearAccessToken();
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::ClearRefreshToken() {
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sender_->auth_service()->ClearRefreshToken();
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::OnOAuth2RefreshTokenChanged() {
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (CanSendRequest()) {
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(
892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        DriveServiceObserver, observers_, OnReadyToSendRequests());
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!HasRefreshToken()) {
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DriveServiceObserver, observers_, OnRefreshTokenInvalid());
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
899eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive
900