blob: 28b618afb486fc2a143a97e6386138a5bb002b5c [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SAVE_TO_DRIVE_SAVE_TO_DRIVE_FLOW_H_
#define CHROME_BROWSER_SAVE_TO_DRIVE_SAVE_TO_DRIVE_FLOW_H_
#include <memory>
#include <optional>
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "chrome/common/extensions/api/pdf_viewer_private.h"
#include "content/public/browser/document_user_data.h"
struct AccountInfo;
namespace content {
class RenderFrameHost;
} // namespace content
class HatsService;
namespace save_to_drive {
class AccountChooser;
class ContentReader;
class DriveUploader;
class SaveToDriveEventDispatcher;
// This class is responsible for orchastrating the entire save to Drive flow
// on the browser process from showing the account chooser, reading the file
// size, and initiating the appropriate drive uploader to save the file to
// Drive. This flow will be tied to the lifetime of the document. It is
// responsible for cleaning up its resources when the flow is stopped.
// This flow should only be called on the UI thread.
class SaveToDriveFlow : public content::DocumentUserData<SaveToDriveFlow> {
public:
using CreateCallback = base::RepeatingCallback<SaveToDriveFlow*(
content::RenderFrameHost* render_frame_host,
std::unique_ptr<SaveToDriveEventDispatcher> event_dispatcher,
std::unique_ptr<ContentReader> content_reader,
std::unique_ptr<AccountChooser> account_chooser,
HatsService* hats_service)>;
// Factory method to create a new instance of `SaveToDriveFlow`. This is
// used to allow for creating a mock flow in tests through
// `SetCreateCallbackForTesting`.
static SaveToDriveFlow* Create(
content::RenderFrameHost* render_frame_host,
std::unique_ptr<SaveToDriveEventDispatcher> event_dispatcher,
std::unique_ptr<ContentReader> content_reader,
std::unique_ptr<AccountChooser> account_chooser,
HatsService* hats_service);
// Sets the callback to create a new instance of `SaveToDriveFlow`. This
// is used to create a mock flow in tests.
static void SetCreateCallbackForTesting(CreateCallback* callback);
SaveToDriveFlow(const SaveToDriveFlow&) = delete;
SaveToDriveFlow& operator=(const SaveToDriveFlow&) = delete;
~SaveToDriveFlow() override;
// Starts the save to Drive flow. Marked virtual for testing.
virtual void Run();
// Cleans up the flow and its resources. This is called when the flow is
// aborted or completed. Marked virtual for testing.
virtual void Stop();
class TestApi {
public:
explicit TestApi(SaveToDriveFlow* flow);
TestApi(const TestApi&) = delete;
TestApi& operator=(const TestApi&) = delete;
~TestApi();
// It will never return `nullptr' before the `flow_` runs.
const ContentReader* content_reader() const;
const DriveUploader* drive_uploader() const;
// It will never return `nullptr' before the `flow_` runs.
const SaveToDriveEventDispatcher* event_dispatcher() const;
// It will never return `nullptr` before the `flow_` runs.
content::RenderFrameHost* rfh();
private:
base::WeakPtr<SaveToDriveFlow> flow_;
};
protected:
SaveToDriveFlow(content::RenderFrameHost* render_frame_host,
std::unique_ptr<SaveToDriveEventDispatcher> event_dispatcher,
std::unique_ptr<ContentReader> content_reader,
std::unique_ptr<AccountChooser> account_chooser,
HatsService* hats_service);
private:
friend class content::DocumentUserData<SaveToDriveFlow>;
friend class TestApi;
struct SaveToDriveAccountInfo {
// The email of the account that is chosen to save the PDF to Drive. It is
// used to construct the URL to open the file in Drive or manage the quota.
std::string email;
// Whether the account is a managed account. It is used to determine whether
// the account is a dasher account and show the correct manage storage URL.
bool is_managed = false;
};
void OnAccountChosen(std::optional<AccountInfo> account_info);
void OnOpenContent(AccountInfo account_info, bool success);
void OnUploadProgress(
extensions::api::pdf_viewer_private::SaveToDriveProgress progress);
void ShowHatsSurveyWithDelay();
std::unique_ptr<SaveToDriveEventDispatcher> event_dispatcher_;
std::unique_ptr<ContentReader> content_reader_;
std::unique_ptr<DriveUploader> drive_uploader_;
std::unique_ptr<AccountChooser> account_chooser_;
raw_ptr<HatsService> hats_service_ = nullptr;
// This is set when an account is chosen.
std::optional<SaveToDriveAccountInfo> save_to_drive_account_info_;
// This is set after the upload starts.
std::optional<extensions::api::pdf_viewer_private::SaveToDriveProgress>
upload_progress_;
base::WeakPtrFactory<SaveToDriveFlow> weak_ptr_factory_{this};
DOCUMENT_USER_DATA_KEY_DECL();
};
} // namespace save_to_drive
#endif // CHROME_BROWSER_SAVE_TO_DRIVE_SAVE_TO_DRIVE_FLOW_H_