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;
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing google_apis::AuthStatusCallback;
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::AuthorizeAppCallback;
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback;
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ChangeList;
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::DownloadActionCallback;
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::EntryActionCallback;
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::FileList;
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::FileResource;
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_OTHER_ERROR;
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_PARSE_ERROR;
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDataErrorCode;
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAboutRequest;
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAboutResourceCallback;
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetAppListCallback;
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetApplistRequest;
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetChangelistRequest;
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetContentCallback;
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetFileRequest;
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetFilelistRequest;
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceEntryCallback;
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using google_apis::GetResourceEntryRequest;
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GetResourceListCallback;
48bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing google_apis::GetShareUrlCallback;
49bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing google_apis::HTTP_NOT_IMPLEMENTED;
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS;
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::InitiateUploadCallback;
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using google_apis::Link;
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback;
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::RequestSender;
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceEntry;
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ResourceList;
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeCallback;
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse;
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::ContinueGetFileListRequest;
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::CopyResourceRequest;
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::CreateDirectoryRequest;
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::DeleteResourceRequest;
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::DownloadFileRequest;
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::GetUploadStatusRequest;
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InitiateUploadExistingFileRequest;
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InitiateUploadNewFileRequest;
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::InsertResourceRequest;
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::RenameResourceRequest;
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::ResumeUploadRequest;
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::TouchResourceRequest;
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::drive::TrashResourceRequest;
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OAuth2 scopes for Drive API.
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveScope[] = "https://www.googleapis.com/auth/drive";
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveAppsReadonlyScope[] =
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    "https://www.googleapis.com/auth/drive.apps.readonly";
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Expected max number of files resources in a http request.
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Be careful not to use something too small because it might overload the
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// server. Be careful not to use something too large because it takes longer
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// time to fetch the result without UI response.
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kMaxNumFilesResourcePerRequest = 500;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kMaxNumFilesResourcePerRequestForSearch = 50;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceList> ParseChangeListJsonToResourceList(
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::Value> value) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ChangeList> change_list(ChangeList::CreateFrom(*value));
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!change_list) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_ptr<ResourceList>();
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ResourceList::CreateFromChangeList(*change_list);
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceList> ParseFileListJsonToResourceList(
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::Value> value) {
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<FileList> file_list(FileList::CreateFrom(*value));
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!file_list) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_ptr<ResourceList>();
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return ResourceList::CreateFromFileList(*file_list);
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Parses JSON value representing either ChangeList or FileList into
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ResourceList.
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceList> ParseResourceListOnBlockingPool(
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::Value> value) {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(value);
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Dispatch the parsing based on kind field.
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ChangeList::HasChangeListKind(*value)) {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ParseChangeListJsonToResourceList(value.Pass());
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FileList::HasFileListKind(*value)) {
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ParseFileListJsonToResourceList(value.Pass());
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The value type is unknown, so give up to parse and return an error.
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return scoped_ptr<ResourceList>();
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Callback invoked when the parsing of resource list is completed,
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// regardless whether it is succeeded or not.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DidParseResourceListOnBlockingPool(
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback,
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ResourceList> resource_list) {
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = resource_list ? HTTP_SUCCESS : GDATA_PARSE_ERROR;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback.Run(error, resource_list.Pass());
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Sends a task to parse the JSON value into ResourceList on blocking pool,
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// with a callback which is called when the task is done.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseResourceListOnBlockingPoolAndRun(
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_refptr<base::TaskRunner> blocking_task_runner,
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback,
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GDataErrorCode error,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<base::Value> value) {
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error != HTTP_SUCCESS) {
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // An error occurs, so run callback immediately.
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceList>());
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PostTaskAndReplyWithResult(
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      blocking_task_runner.get(),
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ParseResourceListOnBlockingPool, base::Passed(&value)),
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&DidParseResourceListOnBlockingPool, callback));
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Parses the FileResource value to ResourceEntry and runs |callback| on the
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// UI thread.
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseResourceEntryAndRun(
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GDataErrorCode error,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FileResource> value) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(error, scoped_ptr<ResourceEntry>());
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Converting to ResourceEntry is cheap enough to do on UI thread.
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry =
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ResourceEntry::CreateFromFileResource(*value);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!entry) {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(GDATA_PARSE_ERROR, scoped_ptr<ResourceEntry>());
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(error, entry.Pass());
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Parses the JSON value to AppList runs |callback| on the UI thread
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// once parsing is done.
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseAppListAndRun(const google_apis::GetAppListCallback& callback,
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        google_apis::GDataErrorCode error,
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        scoped_ptr<base::Value> value) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(error, scoped_ptr<google_apis::AppList>());
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Parsing AppList is cheap enough to do on UI thread.
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<google_apis::AppList> app_list =
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      google_apis::AppList::CreateFrom(*value);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!app_list) {
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(google_apis::GDATA_PARSE_ERROR,
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 scoped_ptr<google_apis::AppList>());
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(error, app_list.Pass());
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Parses the FileResource value to ResourceEntry for upload range request,
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and runs |callback| on the UI thread.
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ParseResourceEntryForUploadRangeAndRun(
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeCallback& callback,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeResponse& response,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FileResource> value) {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(response, scoped_ptr<ResourceEntry>());
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Converting to ResourceEntry is cheap enough to do on UI thread.
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry =
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ResourceEntry::CreateFromFileResource(*value);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!entry) {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(UploadRangeResponse(GDATA_PARSE_ERROR,
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     response.start_position_received,
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     response.end_position_received),
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 scoped_ptr<ResourceEntry>());
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(response, entry.Pass());
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
237a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ExtractOpenUrlAndRun(const std::string& app_id,
238a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          const AuthorizeAppCallback& callback,
239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          GDataErrorCode error,
240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          scoped_ptr<FileResource> value) {
241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(!callback.is_null());
243a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
244a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!value) {
245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    callback.Run(error, GURL());
246a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
247a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
248a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
249a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const std::vector<FileResource::OpenWithLink>& open_with_links =
250a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      value->open_with_links();
251a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  for (size_t i = 0; i < open_with_links.size(); ++i) {
252a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (open_with_links[i].app_id == app_id) {
253a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      callback.Run(HTTP_SUCCESS, open_with_links[i].open_url);
254a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return;
255a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
257a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
258a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Not found.
259a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  callback.Run(GDATA_OTHER_ERROR, GURL());
260a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
261a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The resource ID for the root directory for Drive API is defined in the spec:
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// https://developers.google.com/drive/folder
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDriveApiRootDirectoryResourceId[] = "root";
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveAPIService::DriveAPIService(
269558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    OAuth2TokenService* oauth2_token_service,
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::URLRequestContextGetter* url_request_context_getter,
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::TaskRunner* blocking_task_runner,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& base_url,
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GURL& base_download_url,
274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& wapi_base_url,
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& custom_user_agent)
276558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    : oauth2_token_service_(oauth2_token_service),
277558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      url_request_context_getter_(url_request_context_getter),
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      blocking_task_runner_(blocking_task_runner),
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      url_generator_(base_url, base_download_url),
280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      wapi_url_generator_(wapi_base_url, base_download_url),
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      custom_user_agent_(custom_user_agent) {
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveAPIService::~DriveAPIService() {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (sender_.get())
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    sender_->auth_service()->RemoveObserver(this);
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
291558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid DriveAPIService::Initialize() {
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> scopes;
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scopes.push_back(kDriveScope);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scopes.push_back(kDriveAppsReadonlyScope);
297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // GData WAPI token. These are for GetShareUrl().
299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scopes.push_back(util::kDocsListScope);
300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scopes.push_back(util::kDriveAppsScope);
301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3029ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  sender_.reset(new RequestSender(
3039ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch     new google_apis::AuthService(
304558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch         oauth2_token_service_, url_request_context_getter_, scopes),
3059ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch     url_request_context_getter_,
3069ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch     blocking_task_runner_.get(),
3079ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch     custom_user_agent_));
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sender_->auth_service()->AddObserver(this);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::AddObserver(DriveServiceObserver* observer) {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::RemoveObserver(DriveServiceObserver* observer) {
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool DriveAPIService::CanSendRequest() const {
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return HasRefreshToken();
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string DriveAPIService::CanonicalizeResourceId(
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id) const {
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return drive::util::CanonicalizeResourceId(resource_id);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DriveAPIService::GetRootResourceId() const {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kDriveApiRootDirectoryResourceId;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAllResourceList(
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetResourceListCallback& callback) {
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The simplest way to fetch the all resources list looks files.list method,
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // but it seems impossible to know the returned list's changestamp.
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Thus, instead, we use changes.list method with includeDeleted=false here.
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The returned list should contain only resources currently existing.
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetChangelistRequest(
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          url_generator_,
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          false,  // include deleted
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          0,
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequest,
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetResourceListInDirectory(
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& directory_resource_id,
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback) {
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!directory_resource_id.empty());
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Because children.list method on Drive API v2 returns only the list of
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // children's references, but we need all file resource list.
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // So, here we use files.list method instead, with setting parents query.
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // After the migration from GData WAPI to Drive API v2, we should clean the
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // code up by moving the responsibility to include "parents" in the query
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // to client side.
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We aren't interested in files in trash in this context, neither.
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetFilelistRequest(
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          url_generator_,
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          base::StringPrintf(
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "'%s' in parents and trashed = false",
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              drive::util::EscapeQueryStringValue(
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  directory_resource_id).c_str()),
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequest,
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::Search(
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& search_query,
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GetResourceListCallback& callback) {
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!search_query.empty());
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetFilelistRequest(
392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          url_generator_,
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          drive::util::TranslateQuery(search_query),
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequestForSearch,
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::SearchByTitle(
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& title,
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& directory_resource_id,
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceListCallback& callback) {
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!title.empty());
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string query;
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::StringAppendF(&query, "title = '%s'",
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      drive::util::EscapeQueryStringValue(title).c_str());
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!directory_resource_id.empty()) {
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::StringAppendF(
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &query, " and '%s' in parents",
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        drive::util::EscapeQueryStringValue(directory_resource_id).c_str());
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  query += " and trashed = false";
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetFilelistRequest(
421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          query,
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequest,
425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetChangeList(
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 start_changestamp,
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const GetResourceListCallback& callback) {
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetChangelistRequest(
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          true,  // include deleted
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          start_changestamp,
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          kMaxNumFilesResourcePerRequest,
443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::ContinueGetResourceList(
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& override_url,
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetResourceListCallback& callback) {
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!callback.is_null());
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new ContinueGetFileListRequest(
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          override_url,
458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&ParseResourceListOnBlockingPoolAndRun,
459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     blocking_task_runner_,
460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     callback)));
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetResourceEntry(
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(new GetFileRequest(
470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url_generator_,
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id,
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ParseResourceEntryAndRun, callback)));
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
476bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochCancelCallback DriveAPIService::GetShareUrl(
477bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const std::string& resource_id,
478bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const GURL& embed_origin,
479bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    const GetShareUrlCallback& callback) {
480bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
481bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(!callback.is_null());
482bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
483a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Unfortunately "share url" is not yet supported on Drive API v2.
484a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // So, as a fallback, we use GData WAPI protocol for this method.
485a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // TODO(hidehiko): Get rid of this implementation when share url is
486a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // supported on Drive API v2.
487a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return sender_->StartRequestWithRetry(
488a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new GetResourceEntryRequest(sender_.get(),
489a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  wapi_url_generator_,
490a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  resource_id,
491a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  embed_origin,
492a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                  base::Bind(&util::ParseShareUrlAndRun,
493a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                             callback)));
494bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
495bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
4967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAboutResource(
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetAboutResourceCallback& callback) {
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new GetAboutRequest(
503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetAppList(const GetAppListCallback& callback) {
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(new GetApplistRequest(
513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url_generator_,
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ParseAppListAndRun, callback)));
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::DownloadFile(
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& local_cache_path,
520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& resource_id,
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DownloadActionCallback& download_action_callback,
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GetContentCallback& get_content_callback,
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_callback) {
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!download_action_callback.is_null());
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // get_content_callback may be null.
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new DownloadFileRequest(sender_.get(),
530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              url_generator_,
531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              resource_id,
532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              local_cache_path,
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              download_action_callback,
534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              get_content_callback,
535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              progress_callback));
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::DeleteResource(
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return sender_->StartRequestWithRetry(new TrashResourceRequest(
546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url_generator_,
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id,
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback));
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AddNewDirectory(
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
5547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& directory_title,
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 CreateDirectoryRequest(
561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          parent_resource_id,
5647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          directory_title,
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&ParseResourceEntryAndRun, callback)));
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::CopyResource(
56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
57090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& parent_resource_id,
5717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
57290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
57390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
57490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!callback.is_null());
57590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
577eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new CopyResourceRequest(
578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
57990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          url_generator_,
58090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          resource_id,
58190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          parent_resource_id,
5827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          new_title,
58390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Bind(&ParseResourceEntryAndRun, callback)));
58490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
58590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::CopyHostedDocument(
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
5887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new CopyResourceRequest(
595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
59890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          std::string(),  // parent_resource_id.
5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          new_title,
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&ParseResourceEntryAndRun, callback)));
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::RenameResource(
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& new_title,
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new RenameResourceRequest(
612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
6157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          new_title,
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::TouchResource(
62090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& resource_id,
62190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::Time& modified_date,
62290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::Time& last_viewed_by_me_date,
62390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const GetResourceEntryCallback& callback) {
62490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
62590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!modified_date.is_null());
62690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!last_viewed_by_me_date.is_null());
62790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!callback.is_null());
62890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new TouchResourceRequest(
631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
63290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          url_generator_,
63390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          resource_id,
63490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          modified_date,
63590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          last_viewed_by_me_date,
63690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::Bind(&ParseResourceEntryAndRun, callback)));
63790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
63890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AddResourceToDirectory(
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& 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 InsertResourceRequest(
648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          parent_resource_id,
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::RemoveResourceFromDirectory(
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const EntryActionCallback& callback) {
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new DeleteResourceRequest(
664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          parent_resource_id,
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::InitiateUploadNewFile(
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& parent_resource_id,
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& title,
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new InitiateUploadNewFileRequest(
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          parent_resource_id,
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          title,
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::InitiateUploadExistingFile(
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& etag,
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const InitiateUploadCallback& callback) {
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(
701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new InitiateUploadExistingFileRequest(
702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          url_generator_,
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          resource_id,
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          etag,
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::ResumeUpload(
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_url,
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 start_position,
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 end_position,
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& content_type,
717a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const base::FilePath& local_file_path,
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UploadRangeCallback& callback,
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ProgressCallback& progress_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(
724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      new ResumeUploadRequest(
725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          sender_.get(),
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          upload_url,
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          start_position,
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          end_position,
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_length,
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content_type,
731a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          local_file_path,
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          base::Bind(&ParseResourceEntryForUploadRangeAndRun, callback),
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          progress_callback));
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::GetUploadStatus(
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& upload_url,
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 content_length,
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const UploadRangeCallback& callback) {
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return sender_->StartRequestWithRetry(new GetUploadStatusRequest(
744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
74590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      upload_url,
74690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      content_length,
74790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&ParseResourceEntryForUploadRangeAndRun, callback)));
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)CancelCallback DriveAPIService::AuthorizeApp(
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& resource_id,
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& app_id,
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AuthorizeAppCallback& callback) {
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return sender_->StartRequestWithRetry(new GetFileRequest(
758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      sender_.get(),
759a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      url_generator_,
760a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      resource_id,
761a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::Bind(&ExtractOpenUrlAndRun, app_id, callback)));
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DriveAPIService::HasAccessToken() const {
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->HasAccessToken();
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DriveAPIService::RequestAccessToken(const AuthStatusCallback& callback) {
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!callback.is_null());
7727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const std::string access_token = sender_->auth_service()->access_token();
7747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!access_token.empty()) {
7757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    callback.Run(google_apis::HTTP_NOT_MODIFIED, access_token);
7767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
7777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
7787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Retrieve the new auth token.
7807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sender_->auth_service()->StartAuthentication(callback);
7817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool DriveAPIService::HasRefreshToken() const {
7847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return sender_->auth_service()->HasRefreshToken();
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::ClearAccessToken() {
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sender_->auth_service()->ClearAccessToken();
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::ClearRefreshToken() {
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
7957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  sender_->auth_service()->ClearRefreshToken();
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DriveAPIService::OnOAuth2RefreshTokenChanged() {
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (CanSendRequest()) {
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(
802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        DriveServiceObserver, observers_, OnReadyToSendRequests());
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!HasRefreshToken()) {
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FOR_EACH_OBSERVER(
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DriveServiceObserver, observers_, OnRefreshTokenInvalid());
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive
810