Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / drive / drive_api_service.cc
index ccd60f5..e2f42be 100644 (file)
@@ -9,39 +9,38 @@
 
 #include "base/bind.h"
 #include "base/strings/stringprintf.h"
-#include "base/task_runner_util.h"
-#include "base/values.h"
 #include "chrome/browser/drive/drive_api_util.h"
-#include "chrome/browser/google_apis/auth_service.h"
-#include "chrome/browser/google_apis/drive_api_parser.h"
-#include "chrome/browser/google_apis/drive_api_requests.h"
-#include "chrome/browser/google_apis/gdata_errorcode.h"
-#include "chrome/browser/google_apis/gdata_wapi_parser.h"
-#include "chrome/browser/google_apis/gdata_wapi_requests.h"
-#include "chrome/browser/google_apis/request_sender.h"
 #include "content/public/browser/browser_thread.h"
+#include "google_apis/drive/auth_service.h"
+#include "google_apis/drive/drive_api_parser.h"
+#include "google_apis/drive/drive_api_requests.h"
+#include "google_apis/drive/gdata_errorcode.h"
+#include "google_apis/drive/gdata_wapi_parser.h"
+#include "google_apis/drive/gdata_wapi_requests.h"
+#include "google_apis/drive/request_sender.h"
+#include "google_apis/google_api_keys.h"
 #include "net/url_request/url_request_context_getter.h"
 
 using content::BrowserThread;
+using google_apis::AboutResourceCallback;
 using google_apis::AppList;
 using google_apis::AppListCallback;
 using google_apis::AuthStatusCallback;
 using google_apis::AuthorizeAppCallback;
 using google_apis::CancelCallback;
 using google_apis::ChangeList;
+using google_apis::ChangeListCallback;
 using google_apis::DownloadActionCallback;
 using google_apis::EntryActionCallback;
 using google_apis::FileList;
+using google_apis::FileListCallback;
 using google_apis::FileResource;
+using google_apis::FileResourceCallback;
 using google_apis::GDATA_OTHER_ERROR;
 using google_apis::GDATA_PARSE_ERROR;
 using google_apis::GDataErrorCode;
-using google_apis::AboutResourceCallback;
 using google_apis::GetContentCallback;
-using google_apis::GetResourceEntryCallback;
 using google_apis::GetResourceEntryRequest;
-using google_apis::GetResourceListCallback;
-using google_apis::GetResourceListRequest;
 using google_apis::GetShareUrlCallback;
 using google_apis::HTTP_NOT_IMPLEMENTED;
 using google_apis::HTTP_SUCCESS;
@@ -49,9 +48,6 @@ using google_apis::InitiateUploadCallback;
 using google_apis::Link;
 using google_apis::ProgressCallback;
 using google_apis::RequestSender;
-using google_apis::ResourceEntry;
-using google_apis::ResourceList;
-using google_apis::UploadRangeCallback;
 using google_apis::UploadRangeResponse;
 using google_apis::drive::AboutGetRequest;
 using google_apis::drive::AppsListRequest;
@@ -66,11 +62,13 @@ using google_apis::drive::FilesInsertRequest;
 using google_apis::drive::FilesPatchRequest;
 using google_apis::drive::FilesListRequest;
 using google_apis::drive::FilesListNextPageRequest;
+using google_apis::drive::FilesDeleteRequest;
 using google_apis::drive::FilesTrashRequest;
 using google_apis::drive::GetUploadStatusRequest;
 using google_apis::drive::InitiateUploadExistingFileRequest;
 using google_apis::drive::InitiateUploadNewFileRequest;
 using google_apis::drive::ResumeUploadRequest;
+using google_apis::drive::UploadRangeCallback;
 
 namespace drive {
 
@@ -80,6 +78,8 @@ namespace {
 const char kDriveScope[] = "https://www.googleapis.com/auth/drive";
 const char kDriveAppsReadonlyScope[] =
     "https://www.googleapis.com/auth/drive.apps.readonly";
+const char kDriveAppsScope[] = "https://www.googleapis.com/auth/drive.apps";
+const char kDocsListScope[] = "https://docs.google.com/feeds/";
 
 // Mime type to create a directory.
 const char kFolderMimeType[] = "application/vnd.google-apps.folder";
@@ -93,154 +93,34 @@ const char kFolderMimeType[] = "application/vnd.google-apps.folder";
 // only the total time matters. However, the server seems to have a time limit
 // per single request, which disables us to set the largest value (1000).
 // TODO(kinaba): make it larger when the server gets faster.
-const int kMaxNumFilesResourcePerRequest = 250;
-const int kMaxNumFilesResourcePerRequestForSearch = 50;
+const int kMaxNumFilesResourcePerRequest = 300;
+const int kMaxNumFilesResourcePerRequestForSearch = 100;
 
 // For performance, we declare all fields we use.
 const char kAboutResourceFields[] =
     "kind,quotaBytesTotal,quotaBytesUsed,largestChangeId,rootFolderId";
 const char kFileResourceFields[] =
-    "kind,id,title,createdDate,sharedWithMeDate,downloadUrl,mimeType,"
+    "kind,id,title,createdDate,sharedWithMeDate,mimeType,"
     "md5Checksum,fileSize,labels/trashed,imageMediaMetadata/width,"
     "imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
-    "parents/parentLink,selfLink,thumbnailLink,alternateLink,embedLink,"
-    "modifiedDate,lastViewedByMeDate";
+    "parents(id,parentLink),alternateLink,"
+    "modifiedDate,lastViewedByMeDate,shared";
 const char kFileResourceOpenWithLinksFields[] =
     "kind,id,openWithLinks/*";
 const char kFileListFields[] =
-    "kind,items(kind,id,title,createdDate,sharedWithMeDate,downloadUrl,"
+    "kind,items(kind,id,title,createdDate,sharedWithMeDate,"
     "mimeType,md5Checksum,fileSize,labels/trashed,imageMediaMetadata/width,"
     "imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
-    "parents/parentLink,selfLink,thumbnailLink,alternateLink,embedLink,"
-    "modifiedDate,lastViewedByMeDate),nextLink";
+    "parents(id,parentLink),alternateLink,"
+    "modifiedDate,lastViewedByMeDate,shared),nextLink";
 const char kChangeListFields[] =
-    "kind,items(file(kind,id,title,createdDate,sharedWithMeDate,downloadUrl,"
+    "kind,items(file(kind,id,title,createdDate,sharedWithMeDate,"
     "mimeType,md5Checksum,fileSize,labels/trashed,imageMediaMetadata/width,"
     "imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
-    "parents/parentLink,selfLink,thumbnailLink,alternateLink,embedLink,"
-    "modifiedDate,lastViewedByMeDate),deleted,id,fileId),nextLink,"
+    "parents(id,parentLink),alternateLink,modifiedDate,"
+    "lastViewedByMeDate,shared),deleted,id,fileId,modificationDate),nextLink,"
     "largestChangeId";
 
-// Callback invoked when the parsing of resource list is completed,
-// regardless whether it is succeeded or not.
-void DidConvertToResourceListOnBlockingPool(
-    const GetResourceListCallback& callback,
-    scoped_ptr<ResourceList> resource_list) {
-  GDataErrorCode error = resource_list ? HTTP_SUCCESS : GDATA_PARSE_ERROR;
-  callback.Run(error, resource_list.Pass());
-}
-
-// Converts the FileResource value to ResourceEntry and runs |callback| on the
-// UI thread.
-void ConvertFileEntryToResourceEntryAndRun(
-    const GetResourceEntryCallback& callback,
-    GDataErrorCode error,
-    scoped_ptr<FileResource> value) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (!value) {
-    callback.Run(error, scoped_ptr<ResourceEntry>());
-    return;
-  }
-
-  // Converting to ResourceEntry is cheap enough to do on UI thread.
-  scoped_ptr<ResourceEntry> entry =
-      util::ConvertFileResourceToResourceEntry(*value);
-  if (!entry) {
-    callback.Run(GDATA_PARSE_ERROR, scoped_ptr<ResourceEntry>());
-    return;
-  }
-
-  callback.Run(error, entry.Pass());
-}
-
-// Thin adapter of ConvertFileListToResourceList.
-scoped_ptr<ResourceList> ConvertFileListToResourceList(
-    scoped_ptr<FileList> file_list) {
-  return util::ConvertFileListToResourceList(*file_list);
-}
-
-// Converts the FileList value to ResourceList on blocking pool and runs
-// |callback| on the UI thread.
-void ConvertFileListToResourceListOnBlockingPoolAndRun(
-    scoped_refptr<base::TaskRunner> blocking_task_runner,
-    const GetResourceListCallback& callback,
-    GDataErrorCode error,
-    scoped_ptr<FileList> value) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (!value) {
-    callback.Run(error, scoped_ptr<ResourceList>());
-    return;
-  }
-
-  // Convert the value on blocking pool.
-  base::PostTaskAndReplyWithResult(
-      blocking_task_runner.get(),
-      FROM_HERE,
-      base::Bind(&ConvertFileListToResourceList, base::Passed(&value)),
-      base::Bind(&DidConvertToResourceListOnBlockingPool, callback));
-}
-
-// Thin adapter of ConvertChangeListToResourceList.
-scoped_ptr<ResourceList> ConvertChangeListToResourceList(
-    scoped_ptr<ChangeList> change_list) {
-  return util::ConvertChangeListToResourceList(*change_list);
-}
-
-// Converts the FileList value to ResourceList on blocking pool and runs
-// |callback| on the UI thread.
-void ConvertChangeListToResourceListOnBlockingPoolAndRun(
-    scoped_refptr<base::TaskRunner> blocking_task_runner,
-    const GetResourceListCallback& callback,
-    GDataErrorCode error,
-    scoped_ptr<ChangeList> value) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (!value) {
-    callback.Run(error, scoped_ptr<ResourceList>());
-    return;
-  }
-
-  // Convert the value on blocking pool.
-  base::PostTaskAndReplyWithResult(
-      blocking_task_runner.get(),
-      FROM_HERE,
-      base::Bind(&ConvertChangeListToResourceList, base::Passed(&value)),
-      base::Bind(&DidConvertToResourceListOnBlockingPool, callback));
-}
-
-// Converts the FileResource value to ResourceEntry for upload range request,
-// and runs |callback| on the UI thread.
-void ConvertFileResourceToResourceEntryForUploadRangeAndRun(
-    const UploadRangeCallback& callback,
-    const UploadRangeResponse& response,
-    scoped_ptr<FileResource> value) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  if (!value) {
-    callback.Run(response, scoped_ptr<ResourceEntry>());
-    return;
-  }
-
-  // Converting to ResourceEntry is cheap enough to do on UI thread.
-  scoped_ptr<ResourceEntry> entry =
-      util::ConvertFileResourceToResourceEntry(*value);
-  if (!entry) {
-    callback.Run(UploadRangeResponse(GDATA_PARSE_ERROR,
-                                     response.start_position_received,
-                                     response.end_position_received),
-                 scoped_ptr<ResourceEntry>());
-    return;
-  }
-
-  callback.Run(response, entry.Pass());
-}
-
 void ExtractOpenUrlAndRun(const std::string& app_id,
                           const AuthorizeAppCallback& callback,
                           GDataErrorCode error,
@@ -266,6 +146,16 @@ void ExtractOpenUrlAndRun(const std::string& app_id,
   callback.Run(GDATA_OTHER_ERROR, GURL());
 }
 
+void ExtractShareUrlAndRun(const google_apis::GetShareUrlCallback& callback,
+                           google_apis::GDataErrorCode error,
+                           scoped_ptr<google_apis::ResourceEntry> entry) {
+  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+  const google_apis::Link* share_link =
+      entry ? entry->GetLinkByType(google_apis::Link::LINK_SHARE) : NULL;
+  callback.Run(error, share_link ? share_link->href() : GURL());
+}
+
 // Ignores the |entry|, and runs the |callback|.
 void EntryActionCallbackAdapter(
     const EntryActionCallback& callback,
@@ -282,7 +172,7 @@ const char kDriveApiRootDirectoryResourceId[] = "root";
 DriveAPIService::DriveAPIService(
     OAuth2TokenService* oauth2_token_service,
     net::URLRequestContextGetter* url_request_context_getter,
-    base::TaskRunner* blocking_task_runner,
+    base::SequencedTaskRunner* blocking_task_runner,
     const GURL& base_url,
     const GURL& base_download_url,
     const GURL& wapi_base_url,
@@ -291,7 +181,7 @@ DriveAPIService::DriveAPIService(
       url_request_context_getter_(url_request_context_getter),
       blocking_task_runner_(blocking_task_runner),
       url_generator_(base_url, base_download_url),
-      wapi_url_generator_(wapi_base_url, base_download_url),
+      wapi_url_generator_(wapi_base_url),
       custom_user_agent_(custom_user_agent) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
@@ -308,10 +198,12 @@ void DriveAPIService::Initialize(const std::string& account_id) {
   std::vector<std::string> scopes;
   scopes.push_back(kDriveScope);
   scopes.push_back(kDriveAppsReadonlyScope);
+  scopes.push_back(kDriveAppsScope);
 
-  // GData WAPI token. These are for GetShareUrl().
-  scopes.push_back(util::kDocsListScope);
-  scopes.push_back(util::kDriveAppsScope);
+  // Note: The following scope is used to support GetShareUrl on Drive API v2.
+  // Unfortunately, there is no support on Drive API v2, so we need to fall back
+  // to GData WAPI for the GetShareUrl.
+  scopes.push_back(kDocsListScope);
 
   sender_.reset(new RequestSender(
       new google_apis::AuthService(oauth2_token_service_,
@@ -338,32 +230,26 @@ bool DriveAPIService::CanSendRequest() const {
   return HasRefreshToken();
 }
 
-ResourceIdCanonicalizer DriveAPIService::GetResourceIdCanonicalizer() const {
-  return base::Bind(&drive::util::CanonicalizeResourceId);
-}
-
 std::string DriveAPIService::GetRootResourceId() const {
   return kDriveApiRootDirectoryResourceId;
 }
 
-CancelCallback DriveAPIService::GetAllResourceList(
-    const GetResourceListCallback& callback) {
+CancelCallback DriveAPIService::GetAllFileList(
+    const FileListCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
   FilesListRequest* request = new FilesListRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
-                 blocking_task_runner_, callback));
+      sender_.get(), url_generator_, callback);
   request->set_max_results(kMaxNumFilesResourcePerRequest);
   request->set_q("trashed = false");  // Exclude trashed files.
   request->set_fields(kFileListFields);
   return sender_->StartRequestWithRetry(request);
 }
 
-CancelCallback DriveAPIService::GetResourceListInDirectory(
+CancelCallback DriveAPIService::GetFileListInDirectory(
     const std::string& directory_resource_id,
-    const GetResourceListCallback& callback) {
+    const FileListCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!directory_resource_id.empty());
   DCHECK(!callback.is_null());
@@ -376,30 +262,26 @@ CancelCallback DriveAPIService::GetResourceListInDirectory(
   // to client side.
   // We aren't interested in files in trash in this context, neither.
   FilesListRequest* request = new FilesListRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
-                 blocking_task_runner_, callback));
+      sender_.get(), url_generator_, callback);
   request->set_max_results(kMaxNumFilesResourcePerRequest);
   request->set_q(base::StringPrintf(
       "'%s' in parents and trashed = false",
-      drive::util::EscapeQueryStringValue(directory_resource_id).c_str()));
+      util::EscapeQueryStringValue(directory_resource_id).c_str()));
   request->set_fields(kFileListFields);
   return sender_->StartRequestWithRetry(request);
 }
 
 CancelCallback DriveAPIService::Search(
     const std::string& search_query,
-    const GetResourceListCallback& callback) {
+    const FileListCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!search_query.empty());
   DCHECK(!callback.is_null());
 
   FilesListRequest* request = new FilesListRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
-                 blocking_task_runner_, callback));
+      sender_.get(), url_generator_, callback);
   request->set_max_results(kMaxNumFilesResourcePerRequestForSearch);
-  request->set_q(drive::util::TranslateQuery(search_query));
+  request->set_q(util::TranslateQuery(search_query));
   request->set_fields(kFileListFields);
   return sender_->StartRequestWithRetry(request);
 }
@@ -407,25 +289,23 @@ CancelCallback DriveAPIService::Search(
 CancelCallback DriveAPIService::SearchByTitle(
     const std::string& title,
     const std::string& directory_resource_id,
-    const GetResourceListCallback& callback) {
+    const FileListCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!title.empty());
   DCHECK(!callback.is_null());
 
   std::string query;
   base::StringAppendF(&query, "title = '%s'",
-                      drive::util::EscapeQueryStringValue(title).c_str());
+                      util::EscapeQueryStringValue(title).c_str());
   if (!directory_resource_id.empty()) {
     base::StringAppendF(
         &query, " and '%s' in parents",
-        drive::util::EscapeQueryStringValue(directory_resource_id).c_str());
+        util::EscapeQueryStringValue(directory_resource_id).c_str());
   }
   query += " and trashed = false";
 
   FilesListRequest* request = new FilesListRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
-                 blocking_task_runner_, callback));
+      sender_.get(), url_generator_, callback);
   request->set_max_results(kMaxNumFilesResourcePerRequest);
   request->set_q(query);
   request->set_fields(kFileListFields);
@@ -434,14 +314,12 @@ CancelCallback DriveAPIService::SearchByTitle(
 
 CancelCallback DriveAPIService::GetChangeList(
     int64 start_changestamp,
-    const GetResourceListCallback& callback) {
+    const ChangeListCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
   ChangesListRequest* request = new ChangesListRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertChangeListToResourceListOnBlockingPoolAndRun,
-                 blocking_task_runner_, callback));
+      sender_.get(), url_generator_, callback);
   request->set_max_results(kMaxNumFilesResourcePerRequest);
   request->set_start_change_id(start_changestamp);
   request->set_fields(kChangeListFields);
@@ -450,15 +328,13 @@ CancelCallback DriveAPIService::GetChangeList(
 
 CancelCallback DriveAPIService::GetRemainingChangeList(
     const GURL& next_link,
-    const GetResourceListCallback& callback) {
+    const ChangeListCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!next_link.is_empty());
   DCHECK(!callback.is_null());
 
   ChangesListNextPageRequest* request = new ChangesListNextPageRequest(
-      sender_.get(),
-      base::Bind(&ConvertChangeListToResourceListOnBlockingPoolAndRun,
-                 blocking_task_runner_, callback));
+      sender_.get(), callback);
   request->set_next_link(next_link);
   request->set_fields(kChangeListFields);
   return sender_->StartRequestWithRetry(request);
@@ -466,29 +342,26 @@ CancelCallback DriveAPIService::GetRemainingChangeList(
 
 CancelCallback DriveAPIService::GetRemainingFileList(
     const GURL& next_link,
-    const GetResourceListCallback& callback) {
+    const FileListCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!next_link.is_empty());
   DCHECK(!callback.is_null());
 
   FilesListNextPageRequest* request = new FilesListNextPageRequest(
-      sender_.get(),
-      base::Bind(&ConvertFileListToResourceListOnBlockingPoolAndRun,
-                 blocking_task_runner_, callback));
+      sender_.get(), callback);
   request->set_next_link(next_link);
   request->set_fields(kFileListFields);
   return sender_->StartRequestWithRetry(request);
 }
 
-CancelCallback DriveAPIService::GetResourceEntry(
+CancelCallback DriveAPIService::GetFileResource(
     const std::string& resource_id,
-    const GetResourceEntryCallback& callback) {
+    const FileResourceCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
   FilesGetRequest* request = new FilesGetRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
+      sender_.get(), url_generator_, callback);
   request->set_file_id(resource_id);
   request->set_fields(kFileResourceFields);
   return sender_->StartRequestWithRetry(request);
@@ -510,7 +383,7 @@ CancelCallback DriveAPIService::GetShareUrl(
                                   wapi_url_generator_,
                                   resource_id,
                                   embed_origin,
-                                  base::Bind(&util::ParseShareUrlAndRun,
+                                  base::Bind(&ExtractShareUrlAndRun,
                                              callback)));
 }
 
@@ -530,7 +403,9 @@ CancelCallback DriveAPIService::GetAppList(const AppListCallback& callback) {
   DCHECK(!callback.is_null());
 
   return sender_->StartRequestWithRetry(
-      new AppsListRequest(sender_.get(), url_generator_, callback));
+      new AppsListRequest(sender_.get(), url_generator_,
+                          google_apis::IsGoogleChromeAPIKeyUsed(),
+                          callback));
 }
 
 CancelCallback DriveAPIService::DownloadFile(
@@ -560,6 +435,19 @@ CancelCallback DriveAPIService::DeleteResource(
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
+  FilesDeleteRequest* request = new FilesDeleteRequest(
+      sender_.get(), url_generator_, callback);
+  request->set_file_id(resource_id);
+  request->set_etag(etag);
+  return sender_->StartRequestWithRetry(request);
+}
+
+CancelCallback DriveAPIService::TrashResource(
+    const std::string& resource_id,
+    const EntryActionCallback& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!callback.is_null());
+
   FilesTrashRequest* request = new FilesTrashRequest(
       sender_.get(), url_generator_,
       base::Bind(&EntryActionCallbackAdapter, callback));
@@ -571,14 +459,16 @@ CancelCallback DriveAPIService::DeleteResource(
 CancelCallback DriveAPIService::AddNewDirectory(
     const std::string& parent_resource_id,
     const std::string& directory_title,
-    const GetResourceEntryCallback& callback) {
+    const AddNewDirectoryOptions& options,
+    const FileResourceCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
   FilesInsertRequest* request = new FilesInsertRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
+      sender_.get(), url_generator_, callback);
+  request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
   request->set_mime_type(kFolderMimeType);
+  request->set_modified_date(options.modified_date);
   request->add_parent(parent_resource_id);
   request->set_title(directory_title);
   request->set_fields(kFileResourceFields);
@@ -590,13 +480,12 @@ CancelCallback DriveAPIService::CopyResource(
     const std::string& parent_resource_id,
     const std::string& new_title,
     const base::Time& last_modified,
-    const GetResourceEntryCallback& callback) {
+    const FileResourceCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
   FilesCopyRequest* request = new FilesCopyRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
+      sender_.get(), url_generator_, callback);
   request->set_file_id(resource_id);
   request->add_parent(parent_resource_id);
   request->set_title(new_title);
@@ -605,84 +494,33 @@ CancelCallback DriveAPIService::CopyResource(
   return sender_->StartRequestWithRetry(request);
 }
 
-CancelCallback DriveAPIService::CopyHostedDocument(
-    const std::string& resource_id,
-    const std::string& new_title,
-    const GetResourceEntryCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  FilesCopyRequest* request = new FilesCopyRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
-  request->set_file_id(resource_id);
-  request->set_title(new_title);
-  request->set_fields(kFileResourceFields);
-  return sender_->StartRequestWithRetry(request);
-}
-
-CancelCallback DriveAPIService::MoveResource(
+CancelCallback DriveAPIService::UpdateResource(
     const std::string& resource_id,
     const std::string& parent_resource_id,
     const std::string& new_title,
     const base::Time& last_modified,
-    const GetResourceEntryCallback& callback) {
+    const base::Time& last_viewed_by_me,
+    const FileResourceCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
   FilesPatchRequest* request = new FilesPatchRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
+      sender_.get(), url_generator_, callback);
   request->set_file_id(resource_id);
   request->set_title(new_title);
   if (!parent_resource_id.empty())
     request->add_parent(parent_resource_id);
   if (!last_modified.is_null()) {
+    // Need to set setModifiedDate to true to overwrite modifiedDate.
     request->set_set_modified_date(true);
     request->set_modified_date(last_modified);
   }
-  request->set_fields(kFileResourceFields);
-  return sender_->StartRequestWithRetry(request);
-}
-
-CancelCallback DriveAPIService::RenameResource(
-    const std::string& resource_id,
-    const std::string& new_title,
-    const EntryActionCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!callback.is_null());
-
-  FilesPatchRequest* request = new FilesPatchRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&EntryActionCallbackAdapter, callback));
-  request->set_file_id(resource_id);
-  request->set_title(new_title);
-  request->set_fields(kFileResourceFields);
-  return sender_->StartRequestWithRetry(request);
-}
-
-CancelCallback DriveAPIService::TouchResource(
-    const std::string& resource_id,
-    const base::Time& modified_date,
-    const base::Time& last_viewed_by_me_date,
-    const GetResourceEntryCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!modified_date.is_null());
-  DCHECK(!last_viewed_by_me_date.is_null());
-  DCHECK(!callback.is_null());
-
-  FilesPatchRequest* request = new FilesPatchRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ConvertFileEntryToResourceEntryAndRun, callback));
-  // Need to set setModifiedDate to true to overwrite modifiedDate.
-  request->set_set_modified_date(true);
-
-  // Need to set updateViewedDate to false, otherwise the lastViewedByMeDate
-  // will be set to the request time (not the specified time via request).
-  request->set_update_viewed_date(false);
-
-  request->set_modified_date(modified_date);
-  request->set_last_viewed_by_me_date(last_viewed_by_me_date);
+  if (!last_viewed_by_me.is_null()) {
+    // Need to set updateViewedDate to false, otherwise the lastViewedByMeDate
+    // will be set to the request time (not the specified time via request).
+    request->set_update_viewed_date(false);
+    request->set_last_viewed_by_me_date(last_viewed_by_me);
+  }
   request->set_fields(kFileResourceFields);
   return sender_->StartRequestWithRetry(request);
 }
@@ -720,39 +558,46 @@ CancelCallback DriveAPIService::InitiateUploadNewFile(
     int64 content_length,
     const std::string& parent_resource_id,
     const std::string& title,
+    const InitiateUploadNewFileOptions& options,
     const InitiateUploadCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  return sender_->StartRequestWithRetry(
-      new InitiateUploadNewFileRequest(
-          sender_.get(),
-          url_generator_,
-          content_type,
-          content_length,
-          parent_resource_id,
-          title,
-          callback));
+  InitiateUploadNewFileRequest* request =
+      new InitiateUploadNewFileRequest(sender_.get(),
+                                       url_generator_,
+                                       content_type,
+                                       content_length,
+                                       parent_resource_id,
+                                       title,
+                                       callback);
+  request->set_modified_date(options.modified_date);
+  request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
+  return sender_->StartRequestWithRetry(request);
 }
 
 CancelCallback DriveAPIService::InitiateUploadExistingFile(
     const std::string& content_type,
     int64 content_length,
     const std::string& resource_id,
-    const std::string& etag,
+    const InitiateUploadExistingFileOptions& options,
     const InitiateUploadCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  return sender_->StartRequestWithRetry(
-      new InitiateUploadExistingFileRequest(
-          sender_.get(),
-          url_generator_,
-          content_type,
-          content_length,
-          resource_id,
-          etag,
-          callback));
+  InitiateUploadExistingFileRequest* request =
+      new InitiateUploadExistingFileRequest(sender_.get(),
+                                            url_generator_,
+                                            content_type,
+                                            content_length,
+                                            resource_id,
+                                            options.etag,
+                                            callback);
+  request->set_parent_resource_id(options.parent_resource_id);
+  request->set_title(options.title);
+  request->set_modified_date(options.modified_date);
+  request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
+  return sender_->StartRequestWithRetry(request);
 }
 
 CancelCallback DriveAPIService::ResumeUpload(
@@ -776,8 +621,7 @@ CancelCallback DriveAPIService::ResumeUpload(
           content_length,
           content_type,
           local_file_path,
-          base::Bind(&ConvertFileResourceToResourceEntryForUploadRangeAndRun,
-                     callback),
+          callback,
           progress_callback));
 }
 
@@ -792,8 +636,7 @@ CancelCallback DriveAPIService::GetUploadStatus(
       sender_.get(),
       upload_url,
       content_length,
-      base::Bind(&ConvertFileResourceToResourceEntryForUploadRangeAndRun,
-                 callback)));
+      callback));
 }
 
 CancelCallback DriveAPIService::AuthorizeApp(
@@ -803,46 +646,60 @@ CancelCallback DriveAPIService::AuthorizeApp(
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!callback.is_null());
 
-  FilesGetRequest* request = new FilesGetRequest(
-      sender_.get(), url_generator_,
-      base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
-  request->set_file_id(resource_id);
-  request->set_fields(kFileResourceOpenWithLinksFields);
-  return sender_->StartRequestWithRetry(request);
+  // Files.Authorize is only available for whitelisted clients like official
+  // Google Chrome. In other cases, we fall back to Files.Get that returns the
+  // same value as Files.Authorize without doing authorization. In that case,
+  // the app can open if it was authorized by other means (from whitelisted
+  // clients or drive.google.com web UI.)
+  if (google_apis::IsGoogleChromeAPIKeyUsed()) {
+    google_apis::drive::FilesAuthorizeRequest* request =
+        new google_apis::drive::FilesAuthorizeRequest(
+            sender_.get(), url_generator_,
+            base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
+    request->set_app_id(app_id);
+    request->set_file_id(resource_id);
+    request->set_fields(kFileResourceOpenWithLinksFields);
+    return sender_->StartRequestWithRetry(request);
+  } else {
+    FilesGetRequest* request = new FilesGetRequest(
+        sender_.get(), url_generator_,
+        base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
+    request->set_file_id(resource_id);
+    request->set_fields(kFileResourceOpenWithLinksFields);
+    return sender_->StartRequestWithRetry(request);
+  }
 }
 
-CancelCallback DriveAPIService::GetResourceListInDirectoryByWapi(
-    const std::string& directory_resource_id,
-    const google_apis::GetResourceListCallback& callback) {
+CancelCallback DriveAPIService::UninstallApp(
+    const std::string& app_id,
+    const google_apis::EntryActionCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!directory_resource_id.empty());
   DCHECK(!callback.is_null());
 
-  return sender_->StartRequestWithRetry(
-      new GetResourceListRequest(sender_.get(),
-                                 wapi_url_generator_,
-                                 GURL(),         // No override url
-                                 0,              // start changestamp
-                                 std::string(),  // empty search query
-                                 directory_resource_id,
-                                 callback));
+  google_apis::drive::AppsDeleteRequest* request =
+      new google_apis::drive::AppsDeleteRequest(sender_.get(), url_generator_,
+                                                callback);
+  request->set_app_id(app_id);
+  return sender_->StartRequestWithRetry(request);
 }
 
-CancelCallback DriveAPIService::GetRemainingResourceList(
-    const GURL& next_link,
-    const google_apis::GetResourceListCallback& callback) {
+google_apis::CancelCallback DriveAPIService::AddPermission(
+    const std::string& resource_id,
+    const std::string& email,
+    google_apis::drive::PermissionRole role,
+    const google_apis::EntryActionCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!next_link.is_empty());
   DCHECK(!callback.is_null());
 
-  return sender_->StartRequestWithRetry(
-      new GetResourceListRequest(sender_.get(),
-                                 wapi_url_generator_,
-                                 next_link,
-                                 0,              // start changestamp
-                                 std::string(),  // empty search query
-                                 std::string(),  // no directory resource id
-                                 callback));
+  google_apis::drive::PermissionsInsertRequest* request =
+      new google_apis::drive::PermissionsInsertRequest(sender_.get(),
+                                                       url_generator_,
+                                                       callback);
+  request->set_id(resource_id);
+  request->set_role(role);
+  request->set_type(google_apis::drive::PERMISSION_TYPE_USER);
+  request->set_value(email);
+  return sender_->StartRequestWithRetry(request);
 }
 
 bool DriveAPIService::HasAccessToken() const {