blob: 5d2165d6239749c1f9f23c578bee2fba05f4c97a [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/gdata/gdata_wapi_service.h"
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/message_loop_proxy.h"
#include "chrome/browser/google_apis/drive_api_operations.h"
#include "chrome/browser/google_apis/gdata_operations.h"
#include "chrome/browser/google_apis/gdata_util.h"
#include "chrome/browser/google_apis/operation_runner.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/net/url_util.h"
#include "content/public/browser/browser_thread.h"
using content::BrowserThread;
namespace gdata {
namespace {
const char* GetExportFormatParam(DocumentExportFormat format) {
switch (format) {
case PNG:
return "png";
case HTML:
return "html";
case TXT:
return "txt";
case DOC:
return "doc";
case ODT:
return "odt";
case RTF:
return "rtf";
case ZIP:
return "zip";
case JPEG:
return "jpeg";
case SVG:
return "svg";
case PPT:
return "ppt";
case XLS:
return "xls";
case CSV:
return "csv";
case ODS:
return "ods";
case TSV:
return "tsv";
default:
return "pdf";
}
}
// OAuth2 scopes for the documents API.
const char kDocsListScope[] = "https://docs.google.com/feeds/";
const char kSpreadsheetsScope[] = "https://spreadsheets.google.com/feeds/";
const char kUserContentScope[] = "https://docs.googleusercontent.com/";
const char kDriveAppsScope[] = "https://www.googleapis.com/auth/drive.apps";
} // namespace
GDataWapiService::GDataWapiService()
: profile_(NULL),
runner_(NULL) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}
GDataWapiService::~GDataWapiService() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (runner_.get()) {
runner_->operation_registry()->RemoveObserver(this);
runner_->auth_service()->RemoveObserver(this);
}
}
AuthService* GDataWapiService::auth_service_for_testing() {
return runner_->auth_service();
}
void GDataWapiService::Initialize(Profile* profile) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
profile_ = profile;
std::vector<std::string> scopes;
scopes.push_back(kDocsListScope);
scopes.push_back(kSpreadsheetsScope);
scopes.push_back(kUserContentScope);
// Drive App scope is required for even WAPI v3 apps access.
scopes.push_back(kDriveAppsScope);
runner_.reset(new OperationRunner(profile, scopes));
runner_->Initialize();
runner_->auth_service()->AddObserver(this);
runner_->operation_registry()->AddObserver(this);
}
void GDataWapiService::AddObserver(DriveServiceObserver* observer) {
observers_.AddObserver(observer);
}
void GDataWapiService::RemoveObserver(DriveServiceObserver* observer) {
observers_.RemoveObserver(observer);
}
bool GDataWapiService::CanStartOperation() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return HasRefreshToken();
}
void GDataWapiService::CancelAll() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->CancelAll();
}
bool GDataWapiService::CancelForFilePath(const FilePath& file_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return operation_registry()->CancelForFilePath(file_path);
}
OperationProgressStatusList GDataWapiService::GetProgressStatusList() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return operation_registry()->GetProgressStatusList();
}
void GDataWapiService::Authenticate(const AuthStatusCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->Authenticate(callback);
}
void GDataWapiService::GetDocuments(const GURL& url,
int64 start_changestamp,
const std::string& search_query,
const std::string& directory_resource_id,
const GetDataCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Drive V2 API defines changestamp in int64, while DocumentsList API uses
// int32. This narrowing should not cause any trouble.
GetDocumentsOperation* operation =
new GetDocumentsOperation(operation_registry(),
url,
static_cast<int>(start_changestamp),
search_query,
directory_resource_id,
callback);
runner_->StartOperationWithRetry(operation);
}
void GDataWapiService::GetDocumentEntry(const std::string& resource_id,
const GetDataCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
GetDocumentEntryOperation* operation =
new GetDocumentEntryOperation(operation_registry(),
resource_id,
callback);
runner_->StartOperationWithRetry(operation);
}
void GDataWapiService::GetAccountMetadata(const GetDataCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
GetAccountMetadataOperation* operation =
new GetAccountMetadataOperation(operation_registry(), callback);
runner_->StartOperationWithRetry(operation);
}
void GDataWapiService::GetApplicationInfo(const GetDataCallback& callback) {
// For WAPI, AccountMetadata includes Drive application information.
GetAccountMetadata(callback);
}
void GDataWapiService::DownloadDocument(
const FilePath& virtual_path,
const FilePath& local_cache_path,
const GURL& document_url,
DocumentExportFormat format,
const DownloadActionCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadFile(
virtual_path,
local_cache_path,
chrome_common_net::AppendQueryParameter(document_url,
"exportFormat",
GetExportFormatParam(format)),
callback,
GetContentCallback());
}
void GDataWapiService::DownloadFile(
const FilePath& virtual_path,
const FilePath& local_cache_path,
const GURL& document_url,
const DownloadActionCallback& download_action_callback,
const GetContentCallback& get_content_callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->StartOperationWithRetry(
new DownloadFileOperation(operation_registry(),
download_action_callback,
get_content_callback, document_url,
virtual_path, local_cache_path));
}
void GDataWapiService::DeleteDocument(const GURL& document_url,
const EntryActionCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->StartOperationWithRetry(
new DeleteDocumentOperation(operation_registry(), callback,
document_url));
}
void GDataWapiService::CreateDirectory(
const GURL& parent_content_url,
const FilePath::StringType& directory_name,
const GetDataCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->StartOperationWithRetry(
new CreateDirectoryOperation(operation_registry(), callback,
parent_content_url, directory_name));
}
void GDataWapiService::CopyDocument(const std::string& resource_id,
const FilePath::StringType& new_name,
const GetDataCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->StartOperationWithRetry(
new CopyDocumentOperation(operation_registry(), callback,
resource_id, new_name));
}
void GDataWapiService::RenameResource(const GURL& resource_url,
const FilePath::StringType& new_name,
const EntryActionCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->StartOperationWithRetry(
new RenameResourceOperation(operation_registry(), callback,
resource_url, new_name));
}
void GDataWapiService::AddResourceToDirectory(
const GURL& parent_content_url,
const GURL& resource_url,
const EntryActionCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->StartOperationWithRetry(
new AddResourceToDirectoryOperation(operation_registry(),
callback,
parent_content_url,
resource_url));
}
void GDataWapiService::RemoveResourceFromDirectory(
const GURL& parent_content_url,
const GURL& resource_url,
const std::string& resource_id,
const EntryActionCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->StartOperationWithRetry(
new RemoveResourceFromDirectoryOperation(operation_registry(),
callback,
parent_content_url,
resource_url,
resource_id));
}
void GDataWapiService::InitiateUpload(const InitiateUploadParams& params,
const InitiateUploadCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (params.upload_location.is_empty()) {
if (!callback.is_null())
callback.Run(HTTP_BAD_REQUEST, GURL());
return;
}
runner_->StartOperationWithRetry(
new InitiateUploadOperation(operation_registry(), callback, params));
}
void GDataWapiService::ResumeUpload(const ResumeUploadParams& params,
const ResumeUploadCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->StartOperationWithRetry(
new ResumeUploadOperation(operation_registry(), callback, params));
}
void GDataWapiService::AuthorizeApp(const GURL& resource_url,
const std::string& app_ids,
const GetDataCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
runner_->StartOperationWithRetry(
new AuthorizeAppsOperation(operation_registry(), callback,
resource_url, app_ids));
}
bool GDataWapiService::HasAccessToken() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return runner_->auth_service()->HasAccessToken();
}
bool GDataWapiService::HasRefreshToken() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return runner_->auth_service()->HasRefreshToken();
}
OperationRegistry* GDataWapiService::operation_registry() const {
return runner_->operation_registry();
}
void GDataWapiService::OnOAuth2RefreshTokenChanged() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (CanStartOperation()) {
FOR_EACH_OBSERVER(
DriveServiceObserver, observers_, OnReadyToPerformOperations());
}
}
void GDataWapiService::OnProgressUpdate(
const OperationProgressStatusList& list) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
FOR_EACH_OBSERVER(
DriveServiceObserver, observers_, OnProgressUpdate(list));
}
void GDataWapiService::OnAuthenticationFailed() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
FOR_EACH_OBSERVER(
DriveServiceObserver, observers_, OnAuthenticationFailed());
}
} // namespace gdata