blob: cea9dd4511299f0bff4c7e6cffd7f270c518e6ad [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 <optional>
#include <type_traits>
#include <utility>
#include "base/files/file_path.h"
#include "base/types/expected.h"
#include "base/version.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/web_applications/commands/internal/callback_command.h"
#include "chrome/browser/web_applications/os_integration/os_integration_sub_manager.h"
#include "chrome/browser/web_applications/web_app_command_manager.h"
#include "chrome/browser/web_applications/web_app_filter.h"
#include "chrome/browser/web_applications/web_app_install_params.h"
#include "chrome/browser/web_applications/web_app_management_type.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
#include "components/webapps/browser/installable/installable_metrics.h"
#include "components/webapps/browser/uninstall_result_code.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_cache_client.h"
#endif // BUILDFLAG(IS_CHROMEOS)
class GURL;
class Profile;
class Browser;
namespace content {
class StoragePartitionConfig;
class WebContents;
} // namespace content
namespace url {
class Origin;
} // namespace url
class ScopedKeepAlive;
class ScopedProfileKeepAlive;
namespace web_app {
class ComputedAppSizeWithOrigin;
class IsolatedWebAppInstallSource;
class IsolatedWebAppUrlInfo;
class IsolatedWebAppUpdatePrepareAndStoreCommandUpdateInfo;
class IsolatedWebAppApplyUpdateCommandSuccess;
class IsolationData;
class SignedWebBundleMetadata;
class WebApp;
class WebAppProvider;
enum class ApiApprovalState;
enum class FallbackBehavior;
enum class InstallableCheckResult;
enum class IsolatedInstallabilityCheckResult;
enum class LaunchWebAppWindowSetting;
enum class RunOnOsLoginMode;
enum class ManifestUpdateCheckResult;
enum class ManifestUpdateResult;
enum class ManifestSilentUpdateCheckResult;
enum class NavigateAndTriggerInstallDialogCommandResult;
struct CleanupOrphanedIsolatedWebAppsCommandError;
struct CleanupOrphanedIsolatedWebAppsCommandSuccess;
struct ExternalInstallOptions;
struct ExternallyManagedAppManagerInstallResult;
struct InstallIsolatedWebAppCommandError;
struct InstallIsolatedWebAppCommandSuccess;
struct IsolatedWebAppApplyUpdateCommandError;
struct IsolatedWebAppUpdatePrepareAndStoreCommandError;
struct IsolatedWebAppUpdatePrepareAndStoreCommandSuccess;
struct SynchronizeOsOptions;
struct WebAppIconDiagnosticResult;
struct WebAppInstallInfo;
#if BUILDFLAG(IS_CHROMEOS)
class CleanupBundleCacheSuccess;
class CleanupBundleCacheError;
class CopyBundleToCacheSuccess;
enum class CopyBundleToCacheError;
class GetBundleCachePathSuccess;
enum class GetBundleCachePathError;
class RemoveObsoleteBundleVersionsError;
class RemoveObsoleteBundleVersionsSuccess;
#endif // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_MAC)
enum class RewriteIconResult;
#endif // BUILDFLAG(IS_MAC)
// 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.
//
// Note: When adding new commands to this scheduler, please avoid including them
// in this file, and instead forward declare needed types above.
class WebAppCommandScheduler {
public:
using ManifestWriteCallback =
base::OnceCallback<void(const GURL& url,
const webapps::AppId& app_id,
ManifestUpdateResult result)>;
using InstallIsolatedWebAppCallback = base::OnceCallback<void(
base::expected<InstallIsolatedWebAppCommandSuccess,
InstallIsolatedWebAppCommandError>)>;
using CleanupOrphanedIsolatedWebAppsCallback = base::OnceCallback<void(
base::expected<CleanupOrphanedIsolatedWebAppsCommandSuccess,
CleanupOrphanedIsolatedWebAppsCommandError>)>;
using WebAppIconDiagnosticResultCallback =
base::OnceCallback<void(std::optional<WebAppIconDiagnosticResult>)>;
using WebInstallFromUrlCommandCallback =
base::OnceCallback<void(const webapps::AppId& app_id,
webapps::InstallResultCode code)>;
using UninstallCallback =
base::OnceCallback<void(webapps::UninstallResultCode)>;
using LaunchWebAppCallback =
base::OnceCallback<void(base::WeakPtr<Browser> browser,
base::WeakPtr<content::WebContents> web_contents,
apps::LaunchContainer container)>;
using LaunchWebAppDebugValueCallback =
base::OnceCallback<void(base::WeakPtr<Browser> browser,
base::WeakPtr<content::WebContents> web_contents,
apps::LaunchContainer container,
base::Value debug_value)>;
explicit WebAppCommandScheduler(Profile& profile);
virtual ~WebAppCommandScheduler();
void SetProvider(base::PassKey<WebAppProvider>, WebAppProvider& provider);
void Shutdown();
// Starts a user-initiated installation process from the given `WebContents`.
// This is triggered by a user action, like clicking an install icon in the
// omnibox. It fetches the manifest, shows an install dialog, and if the user
// accepts, it proceeds with the installation. The `fallback_behavior`
// determines what happens if the site is not fully installable (e.g. has no
// manifest).
void FetchManifestAndInstall(webapps::WebappInstallSource install_surface,
base::WeakPtr<content::WebContents> contents,
WebAppInstallDialogCallback dialog_callback,
OnceInstallCallback callback,
FallbackBehavior behavior,
const base::Location& location = FROM_HERE);
// Fetches the `WebAppInstallInfo` for a given `install_url`. This is used
// for installing sub-apps, where the `manifest_id` and optional
// `parent_manifest_id` are known beforehand.
void FetchInstallInfoFromInstallUrl(
webapps::ManifestId manifest_id,
GURL install_url,
webapps::ManifestId parent_manifest_id,
base::OnceCallback<void(std::unique_ptr<WebAppInstallInfo>)> callback);
// Same as the overload above, but without parent_manifest_id.
void FetchInstallInfoFromInstallUrl(
webapps::ManifestId manifest_id,
GURL install_url,
base::OnceCallback<void(std::unique_ptr<WebAppInstallInfo>)> callback);
// Installs a web app from a pre-filled `WebAppInstallInfo` struct, bypassing
// the manifest fetching step. This is for programmatic installations where
// the app's metadata is already known. This version does not install any OS
// hooks and is primarily for testing.
void InstallFromInfoNoIntegrationForTesting(
std::unique_ptr<WebAppInstallInfo> install_info,
bool overwrite_existing_manifest_fields,
webapps::WebappInstallSource install_surface,
OnceInstallCallback install_callback,
const base::Location& location = FROM_HERE);
// Similar to `InstallFromInfoNoIntegrationForTesting`, but allows specifying
// `WebAppInstallParams` to control how OS integration (like shortcuts and
// run-on-os-login) is configured.
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);
using ExternalInstallCallback =
base::OnceCallback<void(ExternallyManagedAppManagerInstallResult)>;
// Installs a web app from an external source, like a policy, default app, or
// system component. This handles loading the install URL, fetching the
// manifest, and creating the web app. It can also install a placeholder if
// the full installation fails, and can replace existing placeholders if
// specified in `external_install_options`.
void InstallExternallyManagedApp(
const ExternalInstallOptions& external_install_options,
std::optional<webapps::AppId> installed_placeholder_app_id,
ExternalInstallCallback installed_callback,
const base::Location& location = FROM_HERE);
void PersistFileHandlersUserChoice(
const webapps::AppId& app_id,
bool allowed,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
using ManifestUpdateCheckCompletedCallback = base::OnceCallback<void(
ManifestUpdateCheckResult check_result,
std::unique_ptr<WebAppInstallInfo> new_install_info)>;
// Checks if an installed web app has an updated manifest. It fetches the new
// manifest from the app's `url`, compares it with the existing one, and if
// there are changes, it may prompt the user for confirmation before applying
// them.
void ScheduleManifestUpdateCheck(
const GURL& url,
const webapps::AppId& app_id,
base::Time check_time,
base::WeakPtr<content::WebContents> contents,
ManifestUpdateCheckCompletedCallback callback,
const base::Location& location = FROM_HERE);
using ManifestSilentUpdateCompletedCallback =
base::OnceCallback<void(ManifestSilentUpdateCheckResult check_result)>;
// A newer version of `ScheduleManifestUpdateCheck` that uses a more
// predictable app updating algorithm. This will eventually replace the
// original.
// For more details, go/predictable-app-updating-design-doc.
void ScheduleManifestSilentUpdate(
const GURL& url,
base::WeakPtr<content::WebContents> contents,
ManifestSilentUpdateCompletedCallback callback,
const base::Location& location = FROM_HERE);
// Finalizes a manifest update by writing the new `install_info` to the
// database. This is often called after all app windows are closed to avoid
// conflicts. The keep-alives ensure the browser doesn't shut down during the
// write. `install_info` must be non-null.
void ScheduleManifestUpdateFinalize(
const GURL& url,
const webapps::AppId& app_id,
std::unique_ptr<WebAppInstallInfo> install_info,
std::unique_ptr<ScopedKeepAlive> keep_alive,
std::unique_ptr<ScopedProfileKeepAlive> profile_keep_alive,
ManifestWriteCallback callback,
const base::Location& location = FROM_HERE);
using FetchInstallabilityForChromeManagementCallback =
base::OnceCallback<void(InstallableCheckResult result,
std::optional<webapps::AppId> app_id)>;
// Checks if a URL is installable as a web app, used for enterprise policy
// checks. Returns whether it's installable, not installable, or already
// installed, along with the app ID if applicable.
void FetchInstallabilityForChromeManagement(
const GURL& url,
base::WeakPtr<content::WebContents> web_contents,
FetchInstallabilityForChromeManagementCallback callback,
const base::Location& location = FROM_HERE);
// The navigation will always succeed. The `result` indicates whether the
// command was able to trigger the install dialog. This opens a new tab,
// navigates to `install_url`, and if the site is installable, it triggers
// the install dialog for the user.
using NavigateAndTriggerInstallDialogCommandCallback =
base::OnceCallback<void(
NavigateAndTriggerInstallDialogCommandResult result)>;
void ScheduleNavigateAndTriggerInstallDialog(
const GURL& install_url,
const GURL& origin_url,
bool is_renderer_initiated,
NavigateAndTriggerInstallDialogCommandCallback callback,
const base::Location& location = FROM_HERE);
// Installs an Isolated Web App from the given `url_info` and
// `install_source`. If `expected_version` is set, this command will refuse to
// install the Isolated Web App if its version does not match.
virtual void InstallIsolatedWebApp(
const IsolatedWebAppUrlInfo& url_info,
const IsolatedWebAppInstallSource& install_source,
const std::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);
// Finds and removes any Isolated Web App data directories on disk that are
// no longer referenced by an installed app in the WebAppRegistrar. This can
// happen if the browser crashes during IWA installation or uninstallation.
virtual void CleanupOrphanedIsolatedApps(
CleanupOrphanedIsolatedWebAppsCallback callback,
const base::Location& call_location = FROM_HERE);
using PrepareAndStoreIsolatedWebAppUpdateCallback = base::OnceCallback<void(
base::expected<IsolatedWebAppUpdatePrepareAndStoreCommandSuccess,
IsolatedWebAppUpdatePrepareAndStoreCommandError>)>;
// Prepares an update for an Isolated Web App. `update_info` specifies the
// location of the update for the IWA referred to in `url_info`. This command
// is safe to run even if the IWA is not installed or already updated. If a
// dry-run of the update succeeds, then the `update_info` is persisted in the
// `IsolationData::pending_update_info()` of the IWA in the Web App database.
virtual void PrepareAndStoreIsolatedWebAppUpdate(
const IsolatedWebAppUpdatePrepareAndStoreCommandUpdateInfo& update_info,
const IsolatedWebAppUrlInfo& url_info,
std::unique_ptr<ScopedKeepAlive> optional_keep_alive,
std::unique_ptr<ScopedProfileKeepAlive> optional_profile_keep_alive,
PrepareAndStoreIsolatedWebAppUpdateCallback callback,
const base::Location& call_location = FROM_HERE);
// Applies a prepared pending update to an Isolated Web App. This command is
// safe to run even if the IWA is not installed or already updated. Regardless
// of whether the update succeeds or fails,
// `IsolationData::pending_update_info` of the IWA in the Web App database
// will be cleared.
virtual void ApplyPendingIsolatedWebAppUpdate(
const IsolatedWebAppUrlInfo& url_info,
std::unique_ptr<ScopedKeepAlive> optional_keep_alive,
std::unique_ptr<ScopedProfileKeepAlive> optional_profile_keep_alive,
base::OnceCallback<
void(base::expected<IsolatedWebAppApplyUpdateCommandSuccess,
IsolatedWebAppApplyUpdateCommandError>)> callback,
const base::Location& call_location = FROM_HERE);
// Checks if a Signed Web Bundle is a valid and installable Isolated Web App.
// It compares the version from the bundle's metadata with an already
// installed app (if one exists) to determine if the bundle is a new install,
// an update, or outdated.
virtual void CheckIsolatedWebAppBundleInstallability(
const SignedWebBundleMetadata& bundle_metadata,
base::OnceCallback<void(IsolatedInstallabilityCheckResult,
std::optional<base::Version>)> callback,
const base::Location& call_location = FROM_HERE);
#if BUILDFLAG(IS_CHROMEOS)
// Gets the path to an IWA bundle in the cache for a given `session_type`. If
// `version` is not provided, it returns the path to the newest cached
// version.
void GetIsolatedWebAppBundleCachePath(
const IsolatedWebAppUrlInfo& url_info,
const std::optional<base::Version>& version,
IwaCacheClient::SessionType session_type,
base::OnceCallback<void(
base::expected<GetBundleCachePathSuccess, GetBundleCachePathError>)>
callback,
const base::Location& call_location = FROM_HERE);
// Copies an IWA bundle file to the cache for a given `session_type`.
void CopyIsolatedWebAppBundleToCache(
const IsolatedWebAppUrlInfo& url_info,
IwaCacheClient::SessionType session_type,
base::OnceCallback<void(base::expected<CopyBundleToCacheSuccess,
CopyBundleToCacheError>)> callback,
const base::Location& call_location = FROM_HERE);
// Cleans all IWA cached bundles for a given `session_type` that are not in
// the `iwas_to_keep_in_cache` list.
void CleanupIsolatedWebAppBundleCache(
const std::vector<web_package::SignedWebBundleId>& iwas_to_keep_in_cache,
IwaCacheClient::SessionType session_type,
base::OnceCallback<void(
base::expected<CleanupBundleCacheSuccess, CleanupBundleCacheError>)>
callback,
const base::Location& call_location = FROM_HERE);
void RemoveObsoleteIsolatedWebAppVersionsCache(
const IsolatedWebAppUrlInfo& url_info,
IwaCacheClient::SessionType session_type,
base::OnceCallback<
void(base::expected<RemoveObsoleteBundleVersionsSuccess,
RemoveObsoleteBundleVersionsError>)> callback,
const base::Location& call_location = FROM_HERE);
#endif // BUILDFLAG(IS_CHROMEOS)
// Calculates the total browsing data size for all installed Isolated Web
// Apps.
void GetIsolatedWebAppBrowsingData(
base::OnceCallback<void(base::flat_map<url::Origin, uint64_t>)> callback,
const base::Location& call_location = FROM_HERE);
// Gets the StoragePartitionConfig for a <controlledframe> within the given
// Isolated Web App. If the partition is persistent (not `in_memory`), it is
// registered in the WebAppProvider.
void GetControlledFramePartition(
const IsolatedWebAppUrlInfo& url_info,
const std::string& partition_name,
bool in_memory,
base::OnceCallback<void(std::optional<content::StoragePartitionConfig>)>
callback,
const base::Location& location = FROM_HERE);
// Installs a web app using data from a sync update. It first tries to fetch a
// live manifest from the app's start URL. If that fails, it falls back to
// using the information from the sync data to ensure the app is installed.
void InstallFromSync(const WebApp& web_app,
OnceInstallCallback callback,
const base::Location& location = FROM_HERE);
// Removes an `install_url` associated with a given `install_source` for an
// app. If `app_id` is not provided, it will act on the first matching app.
// If this is the last install URL for that source, the source is removed. If
// it's the last source for the app, the app is uninstalled.
//
// no remaining install sources for the web app.
// Virtual for testing.
// TODO(crbug.com/40264854): There could potentially be multiple app matches
// for `install_source` and `install_url` when `app_id` is not provided,
// handle this case better than "first matching".
virtual void RemoveInstallUrlMaybeUninstall(
std::optional<webapps::AppId> app_id,
WebAppManagement::Type install_source,
const GURL& install_url,
webapps::WebappUninstallSource uninstall_source,
UninstallCallback callback,
const base::Location& location = FROM_HERE);
// Removes an install management source from a given web app. If this is the
// last source for the app, the app is uninstalled. This also disconnects any
// sub-apps and uninstalls them if they have no other install sources.
//
// Note: This may cause a web app to become user-uninstallable. In that case,
// it will deploy uninstall OS hooks to ensure that it can be uninstallable
// via the OS (windows control panel -> apps -> uninstall).
virtual void RemoveInstallManagementMaybeUninstall(
const webapps::AppId& app_id,
WebAppManagement::Type install_management,
webapps::WebappUninstallSource uninstall_source,
UninstallCallback callback,
const base::Location& location = FROM_HERE);
// Removes all management types that a user can uninstall. If the app was
// installed by default, it will be added to the
// `UserUninstalledPreinstalledWebAppPrefs`.
//
// Note: This may cause a web app to become user-uninstallable. In that case,
// it will deploy uninstall OS hooks to ensure that it can be uninstallable
// via the OS.
void RemoveUserUninstallableManagements(
const webapps::AppId& app_id,
webapps::WebappUninstallSource uninstall_source,
UninstallCallback callback,
const base::Location& location = FROM_HERE);
using UninstallAllUserInstalledWebAppsCallback =
base::OnceCallback<void(const std::optional<std::string>& error_message)>;
// Uninstalls all web apps that were installed by the user.
void UninstallAllUserInstalledWebApps(
webapps::WebappUninstallSource uninstall_source,
UninstallAllUserInstalledWebAppsCallback callback,
const base::Location& location = FROM_HERE);
// Completely removes the web app from the database by removing all management
// types. This is a destructive operation and should be used with caution.
// RemoveInstallUrlMaybeUninstall(), RemoveInstallManagementMaybeUninstall(),
// RemoveUserUninstallableManagements() or UninstallAllUserInstalledWebApps()
// instead.
// Currently, only the WebAppSyncBridge is allowed to invoke this for
// uninstalling web apps, since it is safe to assume that apps marked with
// `is_uninstalling` set to true can be fully removed from the registry.
void RemoveAllManagementTypesAndUninstall(
base::PassKey<WebAppSyncBridge>,
const webapps::AppId& app_id,
webapps::WebappUninstallSource uninstall_source,
UninstallCallback callback,
const base::Location& location = FROM_HERE);
// Sets whether the web app should run on OS login, according to `login_mode`.
void SetRunOnOsLoginMode(const webapps::AppId& app_id,
RunOnOsLoginMode login_mode,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Syncs the run-on-OS-login mode from the web app DB to the OS.
void SyncRunOnOsLoginMode(const webapps::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 webapps::AppId& app_id,
const std::string& protocol_scheme,
ApiApprovalState approval_state,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Sets the app to disabled. This is ChromeOS-specific and a no-op on other
// platforms.
void SetAppIsDisabled(const webapps::AppId& app_id,
bool is_disabled,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Schedules a command that calculates the app and data size of a web app.
void ComputeAppSize(
const webapps::AppId& app_id,
base::OnceCallback<void(std::optional<ComputedAppSizeWithOrigin>)>
callback);
// The command callback type for `ScheduleCallback*`.
// - `lock`: This provides access to read & write parts of the WebAppProvider
// system. See WebAppCommand for information on locks, and you can find them
// in chrome/browser/ewb_applications/locks.
// - `debug_value`: This can be populated with helpful debugging information,
// and will visible in production in chrome://web-app-internals.
template <typename LockType, typename ReturnType>
using CallbackCommand =
base::OnceCallback<ReturnType(LockType& lock,
base::Value::Dict& debug_value)>;
// `ScheduleCallback*` methods provide convenient way to do operations
// on the WebAppProvider system that don't require any async work, but still
// have all of the safety guarantees of commands. All require a:
// - A command callback to do the operation with the lock.
// - A completion callback that is called after the command callback is
// complete (and accepts the command return value as an argument).
// The completion callback is guaranteed to be called, even on system
// shutdown.
//
// `ScheduleCallback` is the equivalent of base::PostTaskAndReply for the
// command system.
template <typename LockType>
void ScheduleCallback(const std::string& operation_name,
LockType::LockDescription lock_description,
CallbackCommand<LockType, void> callback,
base::OnceClosure on_complete,
const base::Location& location = FROM_HERE) {
provider_->command_manager().ScheduleCommand(
std::make_unique<internal::CallbackCommand<LockType>>(
operation_name, std::move(lock_description), std::move(callback),
std::move(on_complete)),
location);
}
// `ScheduleCallbackWithResult` is the equivalent of
// base::PostTaskAndReplyWithResult for the command system.
template <typename LockType,
typename CompletionCallbackArg,
typename CallbackReturnValue = std::decay_t<CompletionCallbackArg>>
void ScheduleCallbackWithResult(
const std::string& operation_name,
LockType::LockDescription lock_description,
CallbackCommand<LockType, CallbackReturnValue> callback,
base::OnceCallback<void(CompletionCallbackArg)> on_complete,
CallbackReturnValue arg_for_shutdown,
const base::Location& location = FROM_HERE) {
provider_->command_manager().ScheduleCommand(
std::make_unique<internal::CallbackCommandWithResult<
LockType, CompletionCallbackArg>>(
operation_name, std::move(lock_description), std::move(callback),
std::move(on_complete), std::move(arg_for_shutdown)),
location);
}
// Clears web app-specific browsing data (like last launch time and badging
// time) within the given 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 webapps::AppId& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory,
const std::optional<GURL>& url_handler_launch_url,
const std::optional<GURL>& protocol_handler_launch_url,
const std::optional<GURL>& file_launch_url,
const std::vector<base::FilePath>& launch_files,
LaunchWebAppCallback callback,
const base::Location& location = FROM_HERE);
// Launches the given app to the given url if specified, or the app
// `start_url` if not. This uses keep-alives to guarantee the
// browser and profile stay alive. Will CHECK-fail if `url` is not valid.
void LaunchApp(const webapps::AppId& app_id,
const std::optional<GURL>& url,
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. If you
// are launching an app, you likely do NOT want to use this method.
void LaunchAppWithCustomParams(apps::AppLaunchParams params,
LaunchWebAppCallback callback,
const base::Location& location = FROM_HERE);
// Takes an app that is already in the registry (e.g. from sync) and installs
// it with OS integration, making it available in the launcher, on the
// desktop, etc.
void InstallAppLocally(const webapps::AppId& app_id,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Forces a synchronization of a web app's OS integration state with the
// database. If `upgrade_to_fully_installed_if_installed` is true and the app
// is installed, this command will upgrade the
// installation status to proto::InstallState::INSTALLED_WITH_OS_INTEGRATION.
void SynchronizeOsIntegration(
const webapps::AppId& app_id,
base::OnceClosure synchronize_callback,
std::optional<SynchronizeOsOptions> synchronize_options = std::nullopt,
bool upgrade_to_fully_installed_if_installed = false,
const base::Location& location = FROM_HERE);
// Sets the user's preferred display mode for an app (e.g., window vs. tab).
// This also ensures OS integration is triggered if the new display mode is
// one that requires it (i.e. anything other than "browser").
void SetUserDisplayMode(const webapps::AppId& app_id,
mojom::UserDisplayMode user_display_mode,
base::OnceClosure callback,
const base::Location& location = FROM_HERE);
#if BUILDFLAG(IS_MAC)
// Rewrites icons for an app if and only if it is a DIY app, where this
// operation has not yet occurred. This will set
// `WebApp::diy_app_icons_masked_on_mac()` to true when
// complete.
void RewriteDiyIcons(const webapps::AppId& app_id,
base::OnceCallback<void(RewriteIconResult)> callback,
const base::Location& location = FROM_HERE);
#endif // BUILDFLAG(IS_MAC)
// Finds web apps that share the same install URLs (possibly across different
// install sources) and dedupes the install URL configs into the most
// recently installed non-placeholder-like web app. See crbug.com/1427340.
void ScheduleDedupeInstallUrls(base::OnceClosure callback,
const base::Location& location = FROM_HERE);
// Sets the user preference for link capturing for the given app. If
// `set_to_preferred` is true, then links in the browser can be launched in
// the app corresponding to app_id, respecting the app's launch handler
// preferences. Additionally, if there are multiple apps within the same
// scope, this will reset the preference on those apps to false.
void SetAppCapturesSupportedLinksDisableOverlapping(
const webapps::AppId app_id,
bool set_to_preferred,
base::OnceClosure done,
const base::Location& location = FROM_HERE);
// Runs a series of icon health checks for `app_id`. See
// `WebAppIconDiagnosticResult` for more information on what diagnostics are
// returned.
void RunIconDiagnosticsForApp(
const webapps::AppId& app_id,
WebAppIconDiagnosticResultCallback result_callback,
const base::Location& location = FROM_HERE);
// Implements the Web Install API (`navigator.install()`).
// Calls `installed_callback` with the `InstallResultCode` and the computed
// manifest id if successful. Used by Web Install API.
void InstallAppFromUrl(const GURL& install_url,
const std::optional<GURL>& manifest_id,
base::WeakPtr<content::WebContents> web_contents,
WebAppInstallDialogCallback dialog_callback,
WebInstallFromUrlCommandCallback installed_callback,
const base::Location& location = FROM_HERE);
base::WeakPtr<WebAppCommandScheduler> GetWeakPtr();
// Safely gets all apps given the WebAppFilter.
void GetAllAppsForFilter(
const WebAppFilter&,
base::OnceCallback<void(std::vector<webapps::AppId>)> callback);
// Synchronizes the os integration of all apps that apply to the filter.
void SynchronizeOsIntegrationForAllApps(const WebAppFilter& filter,
base::OnceClosure callback);
// TODO(crbug.com/40215411): 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_;
raw_ptr<WebAppProvider> provider_ = nullptr;
bool is_in_shutdown_ = false;
// Track how many times ScheduleDedupeInstallUrls() is invoked for metrics to
// check that it's not happening excessively.
// TODO(crbug.com/40264854): Remove once validating that the numbers look okay
// out in the wild.
size_t dedupe_install_urls_run_count_ = 0;
base::WeakPtrFactory<WebAppCommandScheduler> weak_ptr_factory_{this};
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_COMMAND_SCHEDULER_H_