drive_api_service.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/task_runner_util.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/drive/drive_api_util.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/auth_service.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/drive_api_parser.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/google_apis/drive_api_requests.h"
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/google_apis/gdata_errorcode.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/gdata_wapi_parser.h"
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/google_apis/gdata_wapi_requests.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/google_apis/request_sender.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AppList;
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::AppListCallback;
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing google_apis::AuthStatusCallback;
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AuthorizeAppCallback;
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback;
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ChangeList;
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::DownloadActionCallback;
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::EntryActionCallback;
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::FileList;
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::FileResource;
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_OTHER_ERROR;
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_PARSE_ERROR;
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDataErrorCode;
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::AboutResourceCallback;
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetContentCallback;
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceEntryCallback;
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using google_apis::GetResourceEntryRequest;
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceListCallback;
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using google_apis::GetResourceListRequest;
44bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing google_apis::GetShareUrlCallback;
45bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing google_apis::HTTP_NOT_IMPLEMENTED;
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS;
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::InitiateUploadCallback;
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using google_apis::Link;
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback;
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::RequestSender;
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceEntry;
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceList;
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeCallback;
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse;
55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::AboutGetRequest;
56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::AppsListRequest;
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::ChangesListRequest;
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using google_apis::drive::ChangesListNextPageRequest;
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using google_apis::drive::ChildrenDeleteRequest;
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using google_apis::drive::ChildrenInsertRequest;
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::DownloadFileRequest;
62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesCopyRequest;
63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesGetRequest;
64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesInsertRequest;
65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesPatchRequest;
66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesListRequest;
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using google_apis::drive::FilesListNextPageRequest;
68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using google_apis::drive::FilesTrashRequest;
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::GetUploadStatusRequest;
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InitiateUploadExistingFileRequest;
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InitiateUploadNewFileRequest;
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::ResumeUploadRequest;
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OAuth2 scopes for Drive API.
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveScope[] = "https://www.googleapis.com/auth/drive";
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveAppsReadonlyScope[] =
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "https://www.googleapis.com/auth/drive.apps.readonly";
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Mime type to create a directory.
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char kFolderMimeType[] = "application/vnd.google-apps.folder";
85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Expected max number of files resources in a http request.
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Be careful not to use something too small because it might overload the
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// server. Be careful not to use something too large because it takes longer
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// time to fetch the result without UI response.
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kMaxNumFilesResourcePerRequest = 500;
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kMaxNumFilesResourcePerRequestForSearch = 50;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// For performance, we declare all fields we use.
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kAboutResourceFields[] =
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "kind,quotaBytesTotal,quotaBytesUsed,largestChangeId,rootFolderId";
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kFileResourceFields[] =
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "kind,id,title,createdDate,sharedWithMeDate,downloadUrl,mimeType,"
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "md5Checksum,fileSize,labels/trashed,etag,parents/parentLink,selfLink,"
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "thumbnailLink,alternateLink,embedLink,modifiedDate,lastViewedByMeDate";
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kFileResourceOpenWithLinksFields[] =
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "kind,id,openWithLinks/*";
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kFileListFields[] =
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "kind,items(kind,id,title,createdDate,sharedWithMeDate,downloadUrl,"
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "mimeType,md5Checksum,fileSize,labels/trashed,etag,parents/parentLink,"
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "selfLink,thumbnailLink,alternateLink,embedLink,modifiedDate,"
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "lastViewedByMeDate),nextLink";
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kChangeListFields[] =
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "kind,items(file(kind,id,title,createdDate,sharedWithMeDate,downloadUrl,"
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "mimeType,md5Checksum,fileSize,labels/trashed,etag,parents/parentLink,"
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "selfLink,thumbnailLink,alternateLink,embedLink,modifiedDate,"
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "lastViewedByMeDate),deleted,id,fileId),nextLink,largestChangeId";
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Callback invoked when the parsing of resource list is completed,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// regardless whether it is succeeded or not.
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void DidConvertToResourceListOnBlockingPool(
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback,
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ResourceList> resource_list) {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = resource_list ? HTTP_SUCCESS : GDATA_PARSE_ERROR;
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.Run(error, resource_list.Pass());
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Converts the FileResource value to ResourceEntry and runs |callback| on the
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// UI thread.
124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ConvertFileEntryToResourceEntryAndRun(
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GDataErrorCode error,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FileResource> value) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceEntry>());
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Converting to ResourceEntry is cheap enough to do on UI thread.
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry =
138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      util::ConvertFileResourceToResourceEntry(*value);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!entry) {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(GDATA_PARSE_ERROR, scoped_ptr<ResourceEntry>());
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(error, entry.Pass());
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Thin adapter of ConvertFileListToResourceList.
148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)scoped_ptr<ResourceList> ConvertFileListToResourceList(
149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_ptr<FileList> file_list) {
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return util::ConvertFileListToResourceList(*file_list);
151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Converts the FileList value to ResourceList on blocking pool and runs
154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// |callback| on the UI thread.
155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ConvertFileListToResourceListOnBlockingPoolAndRun(
156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_refptr<base::TaskRunner> blocking_task_runner,
157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GetResourceListCallback& callback,
158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    GDataErrorCode error,
159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_ptr<FileList> value) {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceList>());
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Convert the value on blocking pool.
169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      blocking_task_runner.get(),
171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      FROM_HERE,
172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileListToResourceList, base::Passed(&value)),
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&DidConvertToResourceListOnBlockingPool, callback));
174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Thin adapter of ConvertChangeListToResourceList.
177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)scoped_ptr<ResourceList> ConvertChangeListToResourceList(
178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_ptr<ChangeList> change_list) {
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return util::ConvertChangeListToResourceList(*change_list);
180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Converts the FileList value to ResourceList on blocking pool and runs
183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// |callback| on the UI thread.
184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void ConvertChangeListToResourceListOnBlockingPoolAndRun(
185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_refptr<base::TaskRunner> blocking_task_runner,
186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GetResourceListCallback& callback,
187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    GDataErrorCode error,
188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_ptr<ChangeList> value) {
189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!callback.is_null());
191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!value) {
193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceList>());
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Convert the value on blocking pool.
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      blocking_task_runner.get(),
200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      FROM_HERE,
201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertChangeListToResourceList, base::Passed(&value)),
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&DidConvertToResourceListOnBlockingPool, callback));
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Converts the FileResource value to ResourceEntry for upload range request,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and runs |callback| on the UI thread.
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ConvertFileResourceToResourceEntryForUploadRangeAndRun(
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeCallback& callback,
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeResponse& response,
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FileResource> value) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(response, scoped_ptr<ResourceEntry>());
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Converting to ResourceEntry is cheap enough to do on UI thread.
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry =
221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      util::ConvertFileResourceToResourceEntry(*value);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!entry) {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(UploadRangeResponse(GDATA_PARSE_ERROR,
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     response.start_position_received,
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     response.end_position_received),
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 scoped_ptr<ResourceEntry>());
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(response, entry.Pass());
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ExtractOpenUrlAndRun(const std::string& app_id,
234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          const AuthorizeAppCallback& callback,
235a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          GDataErrorCode error,
236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          scoped_ptr<FileResource> value) {
237a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
238a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(!callback.is_null());
239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!value) {
241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    callback.Run(error, GURL());
242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
243a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
244a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const std::vector<FileResource::OpenWithLink>& open_with_links =
246a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      value->open_with_links();
247a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  for (size_t i = 0; i < open_with_links.size(); ++i) {
248a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (open_with_links[i].app_id == app_id) {
249a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      callback.Run(HTTP_SUCCESS, open_with_links[i].open_url);
250a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return;
251a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
252a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
253a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
254a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Not found.
255a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  callback.Run(GDATA_OTHER_ERROR, GURL());
256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
257a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Ignores the |entry|, and runs the |callback|.
2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void EntryActionCallbackAdapter(
2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const EntryActionCallback& callback,
2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    GDataErrorCode error, scoped_ptr<FileResource> entry) {
2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  callback.Run(error);
2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The resource ID for the root directory for Drive API is defined in the spec:
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://developers.google.com/drive/folder
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveApiRootDirectoryResourceId[] = "root";
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveAPIService::DriveAPIService(
272558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    OAuth2TokenService* oauth2_token_service,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::URLRequestContextGetter* url_request_context_getter,
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::TaskRunner* blocking_task_runner,
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& base_url,
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GURL& base_download_url,
277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& wapi_base_url,
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& custom_user_agent)
279558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    : oauth2_token_service_(oauth2_token_service),
280558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      url_request_context_getter_(url_request_context_getter),
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      blocking_task_runner_(blocking_task_runner),
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      url_generator_(base_url, base_download_url),
283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      wapi_url_generator_(wapi_base_url, base_download_url),
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      custom_user_agent_(custom_user_agent) {
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveAPIService::~DriveAPIService() {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (sender_.get())
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    sender_->auth_service()->RemoveObserver(this);
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DriveAPIService::Initialize(const std::string& account_id) {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> scopes;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scopes.push_back(kDriveScope);
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scopes.push_back(kDriveAppsReadonlyScope);
300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // GData WAPI token. These are for GetShareUrl().
302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scopes.push_back(util::kDocsListScope);
303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scopes.push_back(util::kDriveAppsScope);
304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3059ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  sender_.reset(new RequestSender(
30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      new google_apis::AuthService(oauth2_token_service_,
30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                   account_id,
30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                   url_request_context_getter_,
30968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                   scopes),
31068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      url_request_context_getter_,
31168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      blocking_task_runner_.get(),
31268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      custom_user_agent_));
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sender_->auth_service()->AddObserver(this);
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::AddObserver(DriveServiceObserver* observer) {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::RemoveObserver(DriveServiceObserver* observer) {
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DriveAPIService::CanSendRequest() const {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return HasRefreshToken();
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)ResourceIdCanonicalizer DriveAPIService::GetResourceIdCanonicalizer() const {
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return base::Bind(&drive::util::CanonicalizeResourceId);
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DriveAPIService::GetRootResourceId() const {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kDriveApiRootDirectoryResourceId;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAllResourceList(
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetResourceListCallback& callback) {
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FilesListRequest* request = new FilesListRequest(
344424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequest);
34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_q("trashed = false");  // Exclude trashed files.
34968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetResourceListInDirectory(
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& directory_resource_id,
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback) {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!directory_resource_id.empty());
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Because children.list method on Drive API v2 returns only the list of
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // children's references, but we need all file resource list.
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // So, here we use files.list method instead, with setting parents query.
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // After the migration from GData WAPI to Drive API v2, we should clean the
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // code up by moving the responsibility to include "parents" in the query
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // to client side.
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We aren't interested in files in trash in this context, neither.
367424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesListRequest* request = new FilesListRequest(
368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequest);
372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_q(base::StringPrintf(
373424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      "'%s' in parents and trashed = false",
374424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      drive::util::EscapeQueryStringValue(directory_resource_id).c_str()));
37568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::Search(
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& search_query,
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GetResourceListCallback& callback) {
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!search_query.empty());
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesListRequest* request = new FilesListRequest(
387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
388424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
389424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequestForSearch);
391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_q(drive::util::TranslateQuery(search_query));
39268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::SearchByTitle(
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& title,
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& directory_resource_id,
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback) {
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!title.empty());
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string query;
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::StringAppendF(&query, "title = '%s'",
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      drive::util::EscapeQueryStringValue(title).c_str());
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!directory_resource_id.empty()) {
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::StringAppendF(
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &query, " and '%s' in parents",
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        drive::util::EscapeQueryStringValue(directory_resource_id).c_str());
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  query += " and trashed = false";
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
414424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesListRequest* request = new FilesListRequest(
415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequest);
419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_q(query);
42068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
421424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetChangeList(
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 start_changestamp,
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GetResourceListCallback& callback) {
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
430424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ChangesListRequest* request = new ChangesListRequest(
431424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
432424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertChangeListToResourceListOnBlockingPoolAndRun,
433424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 blocking_task_runner_, callback));
434424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_max_results(kMaxNumFilesResourcePerRequest);
435424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_start_change_id(start_changestamp);
43668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kChangeListFields);
437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback DriveAPIService::GetRemainingChangeList(
44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& next_link,
442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GetResourceListCallback& callback) {
443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
44458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!next_link.is_empty());
445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!callback.is_null());
446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
44758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ChangesListNextPageRequest* request = new ChangesListNextPageRequest(
44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      sender_.get(),
44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&ConvertChangeListToResourceListOnBlockingPoolAndRun,
45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 blocking_task_runner_, callback));
45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_next_link(next_link);
45268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kChangeListFields);
45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(request);
454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback DriveAPIService::GetRemainingFileList(
45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& next_link,
458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GetResourceListCallback& callback) {
459424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
46058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!next_link.is_empty());
461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!callback.is_null());
462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
46358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FilesListNextPageRequest* request = new FilesListNextPageRequest(
46458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      sender_.get(),
46558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
46658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 blocking_task_runner_, callback));
46758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_next_link(next_link);
46868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileListFields);
46958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(request);
470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
471424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetResourceEntry(
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
478424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesGetRequest* request = new FilesGetRequest(
479424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
480424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
481424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
48268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
486bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochCancelCallback DriveAPIService::GetShareUrl(
487bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const std::string& resource_id,
488bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const GURL& embed_origin,
489bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const GetShareUrlCallback& callback) {
490bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
491bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(!callback.is_null());
492bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
493a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Unfortunately "share url" is not yet supported on Drive API v2.
494a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // So, as a fallback, we use GData WAPI protocol for this method.
495a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // TODO(hidehiko): Get rid of this implementation when share url is
496a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // supported on Drive API v2.
497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return sender_->StartRequestWithRetry(
498a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new GetResourceEntryRequest(sender_.get(),
499a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  wapi_url_generator_,
500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  resource_id,
501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  embed_origin,
502a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  base::Bind(&util::ParseShareUrlAndRun,
503a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                             callback)));
504bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
505bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAboutResource(
507424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const AboutResourceCallback& callback) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  AboutGetRequest* request =
51268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      new AboutGetRequest(sender_.get(), url_generator_, callback);
51368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kAboutResourceFields);
51468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
517424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CancelCallback DriveAPIService::GetAppList(const AppListCallback& callback) {
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
521424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(
522424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      new AppsListRequest(sender_.get(), url_generator_, callback));
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::DownloadFile(
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& local_cache_path,
527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& resource_id,
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DownloadActionCallback& download_action_callback,
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetContentCallback& get_content_callback,
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_callback) {
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!download_action_callback.is_null());
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // get_content_callback may be null.
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new DownloadFileRequest(sender_.get(),
537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              url_generator_,
538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              resource_id,
539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              local_cache_path,
540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              download_action_callback,
541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              get_content_callback,
542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              progress_callback));
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::DeleteResource(
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesTrashRequest* request = new FilesTrashRequest(
553424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
554424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&EntryActionCallbackAdapter, callback));
555424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
55668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
557424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AddNewDirectory(
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
5627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& directory_title,
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
567424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesInsertRequest* request = new FilesInsertRequest(
568424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
569424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
570424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_mime_type(kFolderMimeType);
571424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->add_parent(parent_resource_id);
572424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_title(directory_title);
57368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
574424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::CopyResource(
57890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
57990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& parent_resource_id,
5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
58168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const base::Time& last_modified,
58290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
58390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
58490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!callback.is_null());
58590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
586424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesCopyRequest* request = new FilesCopyRequest(
587424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
588424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
589424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
590424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->add_parent(parent_resource_id);
591424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_title(new_title);
59268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_modified_date(last_modified);
59368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
594424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
59590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
59690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::CopyHostedDocument(
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
604424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesCopyRequest* request = new FilesCopyRequest(
605424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
606424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
607424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
608424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_title(new_title);
60968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
610424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)CancelCallback DriveAPIService::MoveResource(
6143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& resource_id,
6153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& parent_resource_id,
6163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& new_title,
61768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const base::Time& last_modified,
6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GetResourceEntryCallback& callback) {
6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!callback.is_null());
6213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
622424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesPatchRequest* request = new FilesPatchRequest(
623424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
624424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
625424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
626424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_title(new_title);
627424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!parent_resource_id.empty())
628424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    request->add_parent(parent_resource_id);
62968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!last_modified.is_null()) {
63068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request->set_set_modified_date(true);
63168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request->set_modified_date(last_modified);
63268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
63368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
634424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
6353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::RenameResource(
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
644424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesPatchRequest* request = new FilesPatchRequest(
645424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
646424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&EntryActionCallbackAdapter, callback));
647424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
648424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_title(new_title);
64968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
650424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::TouchResource(
65490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
65590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::Time& modified_date,
65690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::Time& last_viewed_by_me_date,
65790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
65890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
65990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!modified_date.is_null());
66090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!last_viewed_by_me_date.is_null());
66190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!callback.is_null());
66290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
663424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesPatchRequest* request = new FilesPatchRequest(
664424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
665424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Need to set setModifiedDate to true to overwrite modifiedDate.
667424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_set_modified_date(true);
668424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
669424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Need to set updateViewedDate to false, otherwise the lastViewedByMeDate
670424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // will be set to the request time (not the specified time via request).
671424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_update_viewed_date(false);
672424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
673424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_modified_date(modified_date);
674424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_last_viewed_by_me_date(last_viewed_by_me_date);
67568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceFields);
676424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
67790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
67890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AddResourceToDirectory(
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
68658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ChildrenInsertRequest* request =
68758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new ChildrenInsertRequest(sender_.get(), url_generator_, callback);
68858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_folder_id(parent_resource_id);
68958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_id(resource_id);
69058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(request);
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::RemoveResourceFromDirectory(
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
70058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ChildrenDeleteRequest* request =
70158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new ChildrenDeleteRequest(sender_.get(), url_generator_, callback);
70258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_child_id(resource_id);
70358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  request->set_folder_id(parent_resource_id);
70458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(request);
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::InitiateUploadNewFile(
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& title,
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new InitiateUploadNewFileRequest(
718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          parent_resource_id,
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          title,
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::InitiateUploadExistingFile(
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new InitiateUploadExistingFileRequest(
738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          etag,
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::ResumeUpload(
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_url,
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 start_position,
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 end_position,
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
753a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const base::FilePath& local_file_path,
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UploadRangeCallback& callback,
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_callback) {
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new ResumeUploadRequest(
761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          upload_url,
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          start_position,
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          end_position,
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
767a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          local_file_path,
76858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          base::Bind(&ConvertFileResourceToResourceEntryForUploadRangeAndRun,
76958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     callback),
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          progress_callback));
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetUploadStatus(
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_url,
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeCallback& callback) {
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
780eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return sender_->StartRequestWithRetry(new GetUploadStatusRequest(
781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
78290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      upload_url,
78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content_length,
78458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&ConvertFileResourceToResourceEntryForUploadRangeAndRun,
78558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 callback)));
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AuthorizeApp(
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& app_id,
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AuthorizeAppCallback& callback) {
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
795424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FilesGetRequest* request = new FilesGetRequest(
796424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      sender_.get(), url_generator_,
797424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
798424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  request->set_file_id(resource_id);
79968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  request->set_fields(kFileResourceOpenWithLinksFields);
800424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return sender_->StartRequestWithRetry(request);
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)CancelCallback DriveAPIService::GetResourceListInDirectoryByWapi(
80458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& directory_resource_id,
80558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const google_apis::GetResourceListCallback& callback) {
80658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
80758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!directory_resource_id.empty());
80858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!callback.is_null());
80958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
81058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(
81158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new GetResourceListRequest(sender_.get(),
81258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 wapi_url_generator_,
81358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 GURL(),         // No override url
81458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 0,              // start changestamp
81558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 std::string(),  // empty search query
81658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 directory_resource_id,
81758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 callback));
81858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
81958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
82058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)CancelCallback DriveAPIService::GetRemainingResourceList(
82158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& next_link,
82258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const google_apis::GetResourceListCallback& callback) {
82358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
82458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!next_link.is_empty());
82558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!callback.is_null());
82658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
82758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return sender_->StartRequestWithRetry(
82858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new GetResourceListRequest(sender_.get(),
82958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 wapi_url_generator_,
83058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 next_link,
83158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 0,              // start changestamp
83258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 std::string(),  // empty search query
83358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 std::string(),  // no directory resource id
83458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 callback));
83558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
83658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DriveAPIService::HasAccessToken() const {
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
839868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->HasAccessToken();
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DriveAPIService::RequestAccessToken(const AuthStatusCallback& callback) {
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!callback.is_null());
8457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const std::string access_token = sender_->auth_service()->access_token();
8477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!access_token.empty()) {
8487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    callback.Run(google_apis::HTTP_NOT_MODIFIED, access_token);
8497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
8507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
8517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Retrieve the new auth token.
8537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sender_->auth_service()->StartAuthentication(callback);
8547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool DriveAPIService::HasRefreshToken() const {
8577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->HasRefreshToken();
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::ClearAccessToken() {
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sender_->auth_service()->ClearAccessToken();
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::ClearRefreshToken() {
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sender_->auth_service()->ClearRefreshToken();
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::OnOAuth2RefreshTokenChanged() {
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (CanSendRequest()) {
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(
875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        DriveServiceObserver, observers_, OnReadyToSendRequests());
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!HasRefreshToken()) {
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DriveServiceObserver, observers_, OnRefreshTokenInvalid());
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive
883