#ifndef COMPONENTS_DRIVE_DRIVE_UPLOADER_H_
#define COMPONENTS_DRIVE_DRIVE_UPLOADER_H_
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "components/drive/drive_export.h"
#include "components/drive/service/drive_service_interface.h"
#include "google_apis/common/api_error_codes.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/wake_lock_provider.mojom.h"
class GURL;
namespace base {
class FilePath;
class TaskRunner;
}
namespace google_apis {
struct UploadRangeResponse;
}
namespace drive {
class DriveServiceInterface;
using UploadCompletionCallback = base::OnceCallback<void(
google_apis::ApiErrorCode error,
const GURL& upload_location,
std::unique_ptr<google_apis::FileResource> resource_entry)>;
class COMPONENTS_DRIVE_EXPORT DriveUploaderInterface {
public:
virtual ~DriveUploaderInterface() = default;
virtual void StartBatchProcessing() = 0;
virtual void StopBatchProcessing() = 0;
virtual google_apis::CancelCallbackOnce UploadNewFile(
const std::string& parent_resource_id,
const base::FilePath& local_file_path,
const std::string& title,
const std::string& content_type,
const UploadNewFileOptions& options,
UploadCompletionCallback callback,
google_apis::ProgressCallback progress_callback) = 0;
virtual google_apis::CancelCallbackOnce UploadExistingFile(
const std::string& resource_id,
const base::FilePath& local_file_path,
const std::string& content_type,
const UploadExistingFileOptions& options,
UploadCompletionCallback callback,
google_apis::ProgressCallback progress_callback) = 0;
virtual google_apis::CancelCallbackOnce ResumeUploadFile(
const GURL& upload_location,
const base::FilePath& local_file_path,
const std::string& content_type,
UploadCompletionCallback callback,
google_apis::ProgressCallback progress_callback) = 0;
};
class COMPONENTS_DRIVE_EXPORT DriveUploader : public DriveUploaderInterface {
public:
DriveUploader(
DriveServiceInterface* drive_service,
const scoped_refptr<base::TaskRunner>& blocking_task_runner,
mojo::PendingRemote<device::mojom::WakeLockProvider> wake_lock_provider);
DriveUploader(const DriveUploader&) = delete;
DriveUploader& operator=(const DriveUploader&) = delete;
~DriveUploader() override;
void StartBatchProcessing() override;
void StopBatchProcessing() override;
google_apis::CancelCallbackOnce UploadNewFile(
const std::string& parent_resource_id,
const base::FilePath& local_file_path,
const std::string& title,
const std::string& content_type,
const UploadNewFileOptions& options,
UploadCompletionCallback callback,
google_apis::ProgressCallback progress_callback) override;
google_apis::CancelCallbackOnce UploadExistingFile(
const std::string& resource_id,
const base::FilePath& local_file_path,
const std::string& content_type,
const UploadExistingFileOptions& options,
UploadCompletionCallback callback,
google_apis::ProgressCallback progress_callback) override;
google_apis::CancelCallbackOnce ResumeUploadFile(
const GURL& upload_location,
const base::FilePath& local_file_path,
const std::string& content_type,
UploadCompletionCallback callback,
google_apis::ProgressCallback progress_callback) override;
private:
class RefCountedBatchRequest;
struct UploadFileInfo;
typedef base::OnceCallback<void(
std::unique_ptr<UploadFileInfo> upload_file_info)>
StartInitiateUploadCallback;
google_apis::CancelCallbackOnce StartUploadFile(
std::unique_ptr<UploadFileInfo> upload_file_info,
StartInitiateUploadCallback start_initiate_upload_callback);
void StartUploadFileAfterGetFileSize(
std::unique_ptr<UploadFileInfo> upload_file_info,
StartInitiateUploadCallback start_initiate_upload_callback,
std::optional<int64_t> maybe_file_size);
void CallUploadServiceAPINewFile(
const std::string& parent_resource_id,
const std::string& title,
const UploadNewFileOptions& options,
const scoped_refptr<RefCountedBatchRequest>& batch_request,
std::unique_ptr<UploadFileInfo> upload_file_info);
void CallUploadServiceAPIExistingFile(
const std::string& resource_id,
const UploadExistingFileOptions& options,
const scoped_refptr<RefCountedBatchRequest>& batch_request,
std::unique_ptr<UploadFileInfo> upload_file_info);
void OnUploadLocationReceived(
std::unique_ptr<UploadFileInfo> upload_file_info,
google_apis::ApiErrorCode code,
const GURL& upload_location);
void StartGetUploadStatus(std::unique_ptr<UploadFileInfo> upload_file_info);
void UploadNextChunk(std::unique_ptr<UploadFileInfo> upload_file_info);
void OnUploadRangeResponseReceived(
std::unique_ptr<UploadFileInfo> upload_file_info,
const google_apis::UploadRangeResponse& response,
std::unique_ptr<google_apis::FileResource> entry);
void OnUploadProgress(google_apis::ProgressCallback callback,
int64_t start_position,
int64_t total_size,
int64_t progress_of_chunk,
int64_t total_of_chunk);
void UploadFailed(std::unique_ptr<UploadFileInfo> upload_file_info,
google_apis::ApiErrorCode error);
void OnMultipartUploadComplete(
std::unique_ptr<UploadFileInfo> upload_file_info,
google_apis::ApiErrorCode error,
std::unique_ptr<google_apis::FileResource> entry);
device::mojom::WakeLockProvider* GetWakeLockProvider();
base::ThreadChecker thread_checker_;
raw_ptr<DriveServiceInterface, DanglingUntriaged>
drive_service_;
scoped_refptr<base::TaskRunner> blocking_task_runner_;
scoped_refptr<RefCountedBatchRequest> current_batch_request_;
mojo::Remote<device::mojom::WakeLockProvider> wake_lock_provider_;
base::WeakPtrFactory<DriveUploader> weak_ptr_factory_{this};
};
}
#endif