drive_api_service.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/gdata_wapi_parser.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/google_apis/request_sender.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AppList;
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AuthorizeAppCallback;
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback;
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ChangeList;
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::DownloadActionCallback;
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::EntryActionCallback;
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::FileList;
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::FileResource;
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_OTHER_ERROR;
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_PARSE_ERROR;
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDataErrorCode;
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAboutRequest;
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAboutResourceCallback;
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAppListCallback;
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetApplistRequest;
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetChangelistRequest;
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetContentCallback;
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetFileRequest;
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetFilelistRequest;
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceEntryCallback;
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceListCallback;
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS;
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::InitiateUploadCallback;
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback;
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::RequestSender;
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceEntry;
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceList;
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeCallback;
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse;
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::ContinueGetFileListRequest;
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::CopyResourceRequest;
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::CreateDirectoryRequest;
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::DeleteResourceRequest;
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::DownloadFileRequest;
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::GetUploadStatusRequest;
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InitiateUploadExistingFileRequest;
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InitiateUploadNewFileRequest;
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InsertResourceRequest;
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::RenameResourceRequest;
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::ResumeUploadRequest;
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::TouchResourceRequest;
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::TrashResourceRequest;
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OAuth2 scopes for Drive API.
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveScope[] = "https://www.googleapis.com/auth/drive";
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveAppsReadonlyScope[] =
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "https://www.googleapis.com/auth/drive.apps.readonly";
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Expected max number of files resources in a http request.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Be careful not to use something too small because it might overload the
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// server. Be careful not to use something too large because it takes longer
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// time to fetch the result without UI response.
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kMaxNumFilesResourcePerRequest = 500;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kMaxNumFilesResourcePerRequestForSearch = 50;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceList> ParseChangeListJsonToResourceList(
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::Value> value) {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ChangeList> change_list(ChangeList::CreateFrom(*value));
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!change_list) {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_ptr<ResourceList>();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ResourceList::CreateFromChangeList(*change_list);
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceList> ParseFileListJsonToResourceList(
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::Value> value) {
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<FileList> file_list(FileList::CreateFrom(*value));
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!file_list) {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_ptr<ResourceList>();
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ResourceList::CreateFromFileList(*file_list);
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Parses JSON value representing either ChangeList or FileList into
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ResourceList.
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceList> ParseResourceListOnBlockingPool(
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::Value> value) {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(value);
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Dispatch the parsing based on kind field.
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ChangeList::HasChangeListKind(*value)) {
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ParseChangeListJsonToResourceList(value.Pass());
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FileList::HasFileListKind(*value)) {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ParseFileListJsonToResourceList(value.Pass());
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The value type is unknown, so give up to parse and return an error.
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return scoped_ptr<ResourceList>();
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Callback invoked when the parsing of resource list is completed,
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// regardless whether it is succeeded or not.
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DidParseResourceListOnBlockingPool(
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback,
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ResourceList> resource_list) {
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = resource_list ? HTTP_SUCCESS : GDATA_PARSE_ERROR;
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.Run(error, resource_list.Pass());
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Sends a task to parse the JSON value into ResourceList on blocking pool,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// with a callback which is called when the task is done.
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseResourceListOnBlockingPoolAndRun(
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_refptr<base::TaskRunner> blocking_task_runner,
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback,
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GDataErrorCode error,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<base::Value> value) {
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error != HTTP_SUCCESS) {
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // An error occurs, so run callback immediately.
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceList>());
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PostTaskAndReplyWithResult(
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      blocking_task_runner.get(),
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ParseResourceListOnBlockingPool, base::Passed(&value)),
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&DidParseResourceListOnBlockingPool, callback));
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Parses the FileResource value to ResourceEntry and runs |callback| on the
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// UI thread.
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseResourceEntryAndRun(
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GDataErrorCode error,
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FileResource> value) {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceEntry>());
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Converting to ResourceEntry is cheap enough to do on UI thread.
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry =
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ResourceEntry::CreateFromFileResource(*value);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!entry) {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(GDATA_PARSE_ERROR, scoped_ptr<ResourceEntry>());
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(error, entry.Pass());
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Parses the JSON value to AppList runs |callback| on the UI thread
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// once parsing is done.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseAppListAndRun(const google_apis::GetAppListCallback& callback,
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        google_apis::GDataErrorCode error,
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        scoped_ptr<base::Value> value) {
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(error, scoped_ptr<google_apis::AppList>());
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Parsing AppList is cheap enough to do on UI thread.
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<google_apis::AppList> app_list =
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      google_apis::AppList::CreateFrom(*value);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!app_list) {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(google_apis::GDATA_PARSE_ERROR,
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 scoped_ptr<google_apis::AppList>());
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(error, app_list.Pass());
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Parses the FileResource value to ResourceEntry for upload range request,
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and runs |callback| on the UI thread.
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseResourceEntryForUploadRangeAndRun(
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeCallback& callback,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeResponse& response,
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FileResource> value) {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(response, scoped_ptr<ResourceEntry>());
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Converting to ResourceEntry is cheap enough to do on UI thread.
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry =
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ResourceEntry::CreateFromFileResource(*value);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!entry) {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(UploadRangeResponse(GDATA_PARSE_ERROR,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     response.start_position_received,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     response.end_position_received),
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 scoped_ptr<ResourceEntry>());
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(response, entry.Pass());
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ExtractOpenUrlAndRun(const std::string& app_id,
231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          const AuthorizeAppCallback& callback,
232a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          GDataErrorCode error,
233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          scoped_ptr<FileResource> value) {
234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
235a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(!callback.is_null());
236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
237a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!value) {
238a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    callback.Run(error, GURL());
239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const std::vector<FileResource::OpenWithLink>& open_with_links =
243a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      value->open_with_links();
244a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  for (size_t i = 0; i < open_with_links.size(); ++i) {
245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (open_with_links[i].app_id == app_id) {
246a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      callback.Run(HTTP_SUCCESS, open_with_links[i].open_url);
247a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return;
248a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
249a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
250a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
251a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Not found.
252a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  callback.Run(GDATA_OTHER_ERROR, GURL());
253a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
254a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The resource ID for the root directory for Drive API is defined in the spec:
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://developers.google.com/drive/folder
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveApiRootDirectoryResourceId[] = "root";
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveAPIService::DriveAPIService(
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::URLRequestContextGetter* url_request_context_getter,
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::TaskRunner* blocking_task_runner,
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& base_url,
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GURL& base_download_url,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& custom_user_agent)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : url_request_context_getter_(url_request_context_getter),
268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      blocking_task_runner_(blocking_task_runner),
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_(NULL),
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      url_generator_(base_url, base_download_url),
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      custom_user_agent_(custom_user_agent) {
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveAPIService::~DriveAPIService() {
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (sender_.get())
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    sender_->auth_service()->RemoveObserver(this);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::Initialize(Profile* profile) {
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_ = profile;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> scopes;
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scopes.push_back(kDriveScope);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scopes.push_back(kDriveAppsReadonlyScope);
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sender_.reset(new RequestSender(profile,
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  url_request_context_getter_,
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  scopes,
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  custom_user_agent_));
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sender_->Initialize();
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sender_->auth_service()->AddObserver(this);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::AddObserver(DriveServiceObserver* observer) {
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::RemoveObserver(DriveServiceObserver* observer) {
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DriveAPIService::CanSendRequest() const {
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return HasRefreshToken();
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string DriveAPIService::CanonicalizeResourceId(
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id) const {
31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return drive::util::CanonicalizeResourceId(resource_id);
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DriveAPIService::GetRootResourceId() const {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kDriveApiRootDirectoryResourceId;
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAllResourceList(
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetResourceListCallback& callback) {
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The simplest way to fetch the all resources list looks files.list method,
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // but it seems impossible to know the returned list's changestamp.
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Thus, instead, we use changes.list method with includeDeleted=false here.
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The returned list should contain only resources currently existing.
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetChangelistRequest(
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          url_generator_,
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          false,  // include deleted
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          0,
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequest,
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetResourceListInDirectory(
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& directory_resource_id,
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback) {
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!directory_resource_id.empty());
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Because children.list method on Drive API v2 returns only the list of
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // children's references, but we need all file resource list.
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // So, here we use files.list method instead, with setting parents query.
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // After the migration from GData WAPI to Drive API v2, we should clean the
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // code up by moving the responsibility to include "parents" in the query
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // to client side.
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We aren't interested in files in trash in this context, neither.
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetFilelistRequest(
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          url_generator_,
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          base::StringPrintf(
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "'%s' in parents and trashed = false",
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              drive::util::EscapeQueryStringValue(
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  directory_resource_id).c_str()),
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequest,
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::Search(
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& search_query,
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GetResourceListCallback& callback) {
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!search_query.empty());
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetFilelistRequest(
378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          url_generator_,
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          drive::util::TranslateQuery(search_query),
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequestForSearch,
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::SearchByTitle(
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& title,
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& directory_resource_id,
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback) {
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!title.empty());
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string query;
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::StringAppendF(&query, "title = '%s'",
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      drive::util::EscapeQueryStringValue(title).c_str());
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!directory_resource_id.empty()) {
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::StringAppendF(
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &query, " and '%s' in parents",
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        drive::util::EscapeQueryStringValue(directory_resource_id).c_str());
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  query += " and trashed = false";
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetFilelistRequest(
407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          query,
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequest,
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetChangeList(
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 start_changestamp,
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GetResourceListCallback& callback) {
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetChangelistRequest(
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          true,  // include deleted
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          start_changestamp,
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequest,
429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::ContinueGetResourceList(
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& override_url,
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetResourceListCallback& callback) {
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new ContinueGetFileListRequest(
442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          override_url,
444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetResourceEntry(
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(new GetFileRequest(
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url_generator_,
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id,
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ParseResourceEntryAndRun, callback)));
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAboutResource(
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetAboutResourceCallback& callback) {
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetAboutRequest(
469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAppList(const GetAppListCallback& callback) {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(new GetApplistRequest(
479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url_generator_,
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ParseAppListAndRun, callback)));
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::DownloadFile(
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& local_cache_path,
486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& resource_id,
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DownloadActionCallback& download_action_callback,
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetContentCallback& get_content_callback,
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_callback) {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!download_action_callback.is_null());
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // get_content_callback may be null.
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new DownloadFileRequest(sender_.get(),
496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              url_generator_,
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              resource_id,
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              local_cache_path,
499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              download_action_callback,
500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              get_content_callback,
501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              progress_callback));
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::DeleteResource(
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return sender_->StartRequestWithRetry(new TrashResourceRequest(
512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url_generator_,
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id,
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback));
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AddNewDirectory(
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& directory_name,
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new CreateDirectoryRequest(
527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          parent_resource_id,
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          directory_name,
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&ParseResourceEntryAndRun, callback)));
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::CopyResource(
53590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
53690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& parent_resource_id,
53790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& new_name,
53890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
53990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
54090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!callback.is_null());
54190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new CopyResourceRequest(
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
54590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          url_generator_,
54690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          resource_id,
54790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          parent_resource_id,
54890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          new_name,
54990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Bind(&ParseResourceEntryAndRun, callback)));
55090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
55190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::CopyHostedDocument(
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& new_name,
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new CopyResourceRequest(
561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
56490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          std::string(),  // parent_resource_id.
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new_name,
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&ParseResourceEntryAndRun, callback)));
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::RenameResource(
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& new_name,
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new RenameResourceRequest(
578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new_name,
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::TouchResource(
58690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
58790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::Time& modified_date,
58890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::Time& last_viewed_by_me_date,
58990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
59090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
59190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!modified_date.is_null());
59290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!last_viewed_by_me_date.is_null());
59390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!callback.is_null());
59490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new TouchResourceRequest(
597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
59890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          url_generator_,
59990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          resource_id,
60090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          modified_date,
60190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          last_viewed_by_me_date,
60290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Bind(&ParseResourceEntryAndRun, callback)));
60390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
60490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AddResourceToDirectory(
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new InsertResourceRequest(
614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          parent_resource_id,
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::RemoveResourceFromDirectory(
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new DeleteResourceRequest(
630868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          parent_resource_id,
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::InitiateUploadNewFile(
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& title,
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new InitiateUploadNewFileRequest(
648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          parent_resource_id,
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          title,
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::InitiateUploadExistingFile(
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new InitiateUploadExistingFileRequest(
668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          etag,
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::ResumeUpload(
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_url,
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 start_position,
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 end_position,
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
683a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const base::FilePath& local_file_path,
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UploadRangeCallback& callback,
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_callback) {
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new ResumeUploadRequest(
691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          upload_url,
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          start_position,
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          end_position,
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
697a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          local_file_path,
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          base::Bind(&ParseResourceEntryForUploadRangeAndRun, callback),
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          progress_callback));
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetUploadStatus(
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_url,
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeCallback& callback) {
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return sender_->StartRequestWithRetry(new GetUploadStatusRequest(
710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
71190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      upload_url,
71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content_length,
71390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&ParseResourceEntryForUploadRangeAndRun, callback)));
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AuthorizeApp(
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& app_id,
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AuthorizeAppCallback& callback) {
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(new GetFileRequest(
724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
725a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      url_generator_,
726a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      resource_id,
727a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::Bind(&ExtractOpenUrlAndRun, app_id, callback)));
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DriveAPIService::HasAccessToken() const {
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->HasAccessToken();
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DriveAPIService::HasRefreshToken() const {
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->HasRefreshToken();
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::ClearAccessToken() {
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->ClearAccessToken();
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::ClearRefreshToken() {
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->ClearRefreshToken();
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::OnOAuth2RefreshTokenChanged() {
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (CanSendRequest()) {
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(
756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        DriveServiceObserver, observers_, OnReadyToSendRequests());
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!HasRefreshToken()) {
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DriveServiceObserver, observers_, OnRefreshTokenInvalid());
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive
764