blob: 44924e1acbb9bc13185c3b6d57f1c2f0246cbb42 [file] [log] [blame]
// Copyright 2022 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_WEB_APPLICATIONS_WEB_APP_COMMAND_SCHEDULER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_COMMAND_SCHEDULER_H_
#include <memory>
#include "base/containers/flat_map.h"
#include "base/functional/callback_forward.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/version.h"
#include "chrome/browser/web_applications/commands/fetch_installability_for_chrome_management.h"
#include "chrome/browser/web_applications/commands/manifest_update_check_command.h"
#include "chrome/browser/web_applications/commands/manifest_update_finalize_command.h"
#include "chrome/browser/web_applications/commands/navigate_and_trigger_install_dialog_command.h"
#include "chrome/browser/web_applications/external_install_options.h"
#include "chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_command.h"
#include "chrome/browser/web_applications/uninstall/uninstall_job.h"
#include "chrome/browser/web_applications/web_app_install_params.h"
#include "chrome/browser/web_applications/web_app_ui_manager.h"
#include "components/webapps/browser/installable/installable_metrics.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
class GURL;
class Profile;
struct WebAppInstallInfo;
namespace content {
class StoragePartitionConfig;
class WebContents;
} // namespace content
namespace url {
class Origin;
} // namespace url
class ScopedKeepAlive;
class ScopedProfileKeepAlive;
namespace web_app {
class IsolatedWebAppUrlInfo;
class WebApp;
class WebAppDataRetriever;
class WebAppProvider;
class WebAppUrlLoader;
class WebContentsManager;
enum class ApiApprovalState;
struct IsolationData;
struct SynchronizeOsOptions;
// The command scheduler is the main API to access the web app system. The
// scheduler internally ensures:
// * Operations occur after the WebAppProvider is ready (so you don't have to
// manually wait for this).
// * Operations are isolated from other operations in the system (currently
// implemented using `WebAppCommand`s) to prevent race conditions while
// reading/writing from the various data storage of the system.
// * Operations have the necessary dependencies from the WebAppProvider system.
class WebAppCommandScheduler {
public:
using ManifestWriteCallback =
ManifestUpdateFinalizeCommand::ManifestWriteCallback;
using InstallIsolatedWebAppCallback = base::OnceCallback<void(
base::expected<InstallIsolatedWebAppCommandSuccess,
InstallIsolatedWebAppCommandError>)>;
WebAppCommandScheduler(Profile& profile, WebAppProvider* provider);
virtual ~WebAppCommandScheduler();
void Start();
void Shutdown();
// User initiated install that uses current `WebContents` to fetch manifest
// and install the web app.
void FetchManifestAndInstall(webapps::WebappInstallSource install_surface,
base::WeakPtr<content::WebContents> contents,
bool bypass_service_worker_check,
WebAppInstallDialogCallback dialog_callback,
OnceInstallCallback callback,
bool use_fallback,
const base::Location& location = FROM_HERE);
// Install with provided `WebAppInstallInfo` instead of fetching data from
// manifest.
// `InstallFromInfo` doesn't install OS hooks. `InstallFromInfoWithParams`
// install OS hooks when they are set in `install_params`.
void InstallFromInfo(std::unique_ptr<WebAppInstallInfo> install_info,
bool overwrite_existing_manifest_fields,
webapps::WebappInstallSource install_surface,
OnceInstallCallback install_callback,
const base::Location& location = FROM_HERE);
void InstallFromInfoWithParams(
std::unique_ptr<WebAppInstallInfo> install_info,
bool overwrite_existing_manifest_fields,
webapps::WebappInstallSource install_surface,
OnceInstallCallback install_callback,
const WebAppInstallParams& install_params,
const base::Location& location = FROM_HERE);
void InstallFromInfoWithParams(
std::unique_ptr<WebAppInstallInfo> install_info,
bool overwrite_existing_manifest_fields,
webapps::WebappInstallSource install_surface,
base::OnceCallback<void(const AppId& app_id,
webapps::InstallResultCode code,
bool did_uninstall_and_replace)> install_callback,
const WebAppInstallParams& install_params,
const std::vector<AppId>& apps_to_uninstall,
const base::Location& location = FROM_HERE);
// Install web apps managed by `ExternallyInstalledAppManager`.
void InstallExternallyManagedApp(
const ExternalInstallOptions& external_install_options,
base::OnceCallback<void(const AppId& app_id,
webapps::InstallResultCode code,
bool did_uninstall_and_replace)> install_callback,
base::WeakPtr<content::WebContents> contents,
std::unique_ptr<WebAppDataRetriever> data_retriever,
WebAppUrlLoader* web_app_url_loader,
const base::Location& location = FROM_HERE);
// Install a placeholder app, this is used during externally managed install
// flow when url load fails.
void InstallPlaceholder(
const ExternalInstallOptions& install_options,
base::OnceCallback<void(const AppId& app_id,
webapps::InstallResultCode code,
bool did_uninstall_and_replace)> callback,
base::WeakPtr<content::WebContents> web_contents,
const base::Location& location = FROM_HERE);
void PersistFileHandlersUserChoice(
const AppId& app_id,
bool allowed,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Schedule a command that performs fetching data from the manifest
// for a manifest update.
void ScheduleManifestUpdateCheck(
const GURL& url,
const AppId& app_id,
base::Time check_time,
base::WeakPtr<content::WebContents> contents,
ManifestUpdateCheckCommand::CompletedCallback callback,
const base::Location& location = FROM_HERE);
// Schedules a command that performs the data writes into the DB for
// completion of the manifest update.
void ScheduleManifestUpdateFinalize(
const GURL& url,
const AppId& app_id,
WebAppInstallInfo install_info,
std::unique_ptr<ScopedKeepAlive> keep_alive,
std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive,
ManifestWriteCallback callback,
const base::Location& location = FROM_HERE);
void FetchInstallabilityForChromeManagement(
const GURL& url,
base::WeakPtr<content::WebContents> web_contents,
FetchInstallabilityForChromeManagementCallback callback,
const base::Location& location = FROM_HERE);
void ScheduleNavigateAndTriggerInstallDialog(
const GURL& install_url,
const GURL& origin_url,
bool is_renderer_initiated,
NavigateAndTriggerInstallDialogCommandCallback callback,
const base::Location& location = FROM_HERE);
// Schedules a command that installs the Isolated Web App described by the
// given IsolatedWebAppUrlInfo and IsolationData. If `expected_version` is
// set, then this command will refuse to install the Isolated Web App if its
// version does not match.
virtual void InstallIsolatedWebApp(
const IsolatedWebAppUrlInfo& url_info,
const IsolatedWebAppLocation& location,
const absl::optional<base::Version>& expected_version,
std::unique_ptr<ScopedKeepAlive> optional_keep_alive,
std::unique_ptr<ScopedProfileKeepAlive> optional_profile_keep_alive,
InstallIsolatedWebAppCallback callback,
const base::Location& call_location = FROM_HERE);
// Computes the browsing data size of all installed Isolated Web Apps.
void GetIsolatedWebAppBrowsingData(
base::OnceCallback<void(base::flat_map<url::Origin, int64_t>)> callback,
const base::Location& call_location = FROM_HERE);
// Registers a <controlledframe>'s StoragePartition with the given Isolated
// Web App.
void GetControlledFramePartition(
const IsolatedWebAppUrlInfo& url_info,
const std::string& partition_name,
bool in_memory,
base::OnceCallback<void(absl::optional<content::StoragePartitionConfig>)>
callback,
const base::Location& location = FROM_HERE);
// Scheduler a command that installs a web app from sync.
void InstallFromSync(const WebApp& web_app,
OnceInstallCallback callback,
const base::Location& location = FROM_HERE);
// Schedules a command that, if `external_install_source` is set, removes the
// install source from a web app, otherwise uninstalls the web app. If the
// last install source of a web app is removed the web app will be
// uninstalled. If the uninstalled web app has sub apps their parent install
// source will be removed, uninstalling them too if they no longer have any
// install sources, this process will repeat as many times as needed.
// TODO(crbug.com/1427340): Expose this as separate RemoveInstallUrl(),
// RemoveInstallSource() and UninstallWebApp() methods.
void Uninstall(const AppId& app_id,
absl::optional<WebAppManagement::Type> external_install_source,
webapps::WebappUninstallSource uninstall_source,
UninstallJob::Callback callback,
const base::Location& location = FROM_HERE);
// Schedules a command that updates run on os login to provided `login_mode`
// for a web app.
void SetRunOnOsLoginMode(const AppId& app_id,
RunOnOsLoginMode login_mode,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Schedules a command that syncs the run on os login mode from web app DB to
// OS.
void SyncRunOnOsLoginMode(const AppId& app_id,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Updates the approved or disallowed protocol list for the given app. If
// necessary, it also updates the protocol registration with the OS.
void UpdateProtocolHandlerUserApproval(
const AppId& app_id,
const std::string& protocol_scheme,
ApiApprovalState approval_state,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Set app to disabled, This is Chrome OS specific and no-op on other
// platforms.
void SetAppIsDisabled(const AppId& app_id,
bool is_disabled,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Schedules provided callback after `lock` is granted. The callback can
// access web app resources through the `lock`. The `operation_name` is used
// describe this operation in the WebAppCommandManager log, surfaced in
// chrome://web-app-internals for debugging purposes.
// If the system is shutting down, or has already shut down, then the callback
// will not be called & will simply be destroyed.
template <typename LockType,
typename DescriptionType = typename LockType::LockDescription>
void ScheduleCallbackWithLock(
const std::string& operation_name,
std::unique_ptr<DescriptionType> lock_description,
base::OnceCallback<void(LockType& lock)> callback,
const base::Location& location = FROM_HERE);
// Same as above, but the callback can return a debug value to also be used in
// WebAppCommandManager logs, viewable from chrome://web-app-internals.
template <typename LockType,
typename DescriptionType = typename LockType::LockDescription>
void ScheduleCallbackWithLock(
const std::string& operation_name,
std::unique_ptr<DescriptionType> lock_description,
base::OnceCallback<base::Value(LockType& lock)> callback,
const base::Location& location = FROM_HERE);
// Schedules to clear the browsing data for web app, given the inclusive time
// range.
void ClearWebAppBrowsingData(const base::Time& begin_time,
const base::Time& end_time,
base::OnceClosure done,
const base::Location& location = FROM_HERE);
// Launches the given app. This call also uses keep-alives to guarantee that
// the browser and profile will not destruct before the launch is complete.
void LaunchApp(const AppId& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory,
const absl::optional<GURL>& url_handler_launch_url,
const absl::optional<GURL>& protocol_handler_launch_url,
const absl::optional<GURL>& file_launch_url,
const std::vector<base::FilePath>& launch_files,
LaunchWebAppCallback callback,
const base::Location& location = FROM_HERE);
// Used to launch apps with a custom launch params. This does not respect the
// configuration of the app, and will respect whatever the params say.
void LaunchAppWithCustomParams(apps::AppLaunchParams params,
LaunchWebAppCallback callback,
const base::Location& location = FROM_HERE);
// Used to locally install an app from the chrome://apps page, triggered
// by the AppLauncherHandler.
void InstallAppLocally(const AppId& app_id,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Used to schedule a synchronization of a web app's OS states with the
// current DB states.
void SynchronizeOsIntegration(
const AppId& app_id,
base::OnceClosure synchronize_callback,
absl::optional<SynchronizeOsOptions> synchronize_options = absl::nullopt,
const base::Location& location = FROM_HERE);
// TODO(https://crbug.com/1298130): expose all commands for web app
// operations.
private:
void LaunchApp(apps::AppLaunchParams params,
LaunchWebAppWindowSetting option,
LaunchWebAppCallback callback,
const base::Location& location);
void LaunchAppWithKeepAlives(
apps::AppLaunchParams params,
LaunchWebAppWindowSetting option,
LaunchWebAppCallback callback,
std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive,
std::unique_ptr<ScopedKeepAlive> browser_keep_alive,
const base::Location& location);
bool IsShuttingDown() const;
const raw_ref<Profile> profile_;
// Safe because we live on the WebAppProvider.
// raw_ptr is required due to the FakeWebAppCommandScheduler not having a
// WebAppProvider.
const raw_ptr<WebAppProvider> provider_;
bool is_in_shutdown_ = false;
// TODO(http://b/262606416): Remove this when fully transitioned to
// WebContentsManager.
std::unique_ptr<WebAppUrlLoader> url_loader_;
base::WeakPtrFactory<WebAppCommandScheduler> weak_ptr_factory_{this};
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_COMMAND_SCHEDULER_H_