| // Copyright 2018 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. |
| |
| #ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INSTALL_FINALIZER_H_ |
| #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INSTALL_FINALIZER_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <vector> |
| |
| #include "base/callback_forward.h" |
| #include "base/containers/flat_set.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "chrome/browser/ash/system_web_apps/types/system_web_app_data.h" |
| #include "chrome/browser/web_applications/os_integration/os_integration_manager.h" |
| #include "chrome/browser/web_applications/web_app_chromeos_data.h" |
| #include "chrome/browser/web_applications/web_app_constants.h" |
| #include "chrome/browser/web_applications/web_app_id.h" |
| #include "chrome/browser/web_applications/web_app_install_info.h" |
| #include "chrome/browser/web_applications/web_app_uninstall_job.h" |
| #include "components/webapps/browser/install_result_code.h" |
| #include "components/webapps/browser/installable/installable_metrics.h" |
| #include "third_party/skia/include/core/SkBitmap.h" |
| |
| class Profile; |
| |
| namespace webapps { |
| enum class UninstallResultCode; |
| enum class WebappUninstallSource; |
| } |
| |
| namespace web_app { |
| |
| class WebAppSyncBridge; |
| class WebAppUiManager; |
| class WebApp; |
| class WebAppIconManager; |
| class WebAppInstallManager; |
| class WebAppPolicyManager; |
| class WebAppRegistrar; |
| class WebAppTranslationManager; |
| class WebAppUninstallJob; |
| |
| // An finalizer for the installation process, represents the last step. |
| // Takes WebAppInstallInfo as input, writes data to disk (e.g icons, shortcuts) |
| // and registers an app. |
| class WebAppInstallFinalizer { |
| public: |
| using InstallFinalizedCallback = |
| base::OnceCallback<void(const AppId& app_id, |
| webapps::InstallResultCode code, |
| OsHooksErrors os_hooks_errors)>; |
| using UninstallWebAppCallback = |
| base::OnceCallback<void(webapps::UninstallResultCode code)>; |
| using RepeatingUninstallCallback = |
| base::RepeatingCallback<void(const AppId& app_id, |
| webapps::UninstallResultCode code)>; |
| |
| struct FinalizeOptions { |
| explicit FinalizeOptions(webapps::WebappInstallSource install_surface); |
| ~FinalizeOptions(); |
| FinalizeOptions(const FinalizeOptions&); |
| |
| const WebAppManagement::Type source; |
| const webapps::WebappInstallSource install_surface; |
| bool locally_installed = true; |
| bool overwrite_existing_manifest_fields = true; |
| |
| absl::optional<WebAppChromeOsData> chromeos_data; |
| absl::optional<ash::SystemWebAppData> system_web_app_data; |
| absl::optional<AppId> parent_app_id; |
| |
| // If true, OsIntegrationManager::InstallOsHooks won't be called at all, |
| // meaning that all other OS Hooks related parameters below will be ignored. |
| bool bypass_os_hooks = false; |
| |
| // These OS shortcut fields can't be true if |locally_installed| is false. |
| // They only have an effect when |bypass_os_hooks| is false. |
| bool add_to_applications_menu = true; |
| bool add_to_desktop = true; |
| bool add_to_quick_launch_bar = true; |
| }; |
| |
| explicit WebAppInstallFinalizer(Profile* profile); |
| WebAppInstallFinalizer(const WebAppInstallFinalizer&) = delete; |
| WebAppInstallFinalizer& operator=(const WebAppInstallFinalizer&) = delete; |
| virtual ~WebAppInstallFinalizer(); |
| |
| // All methods below are |virtual| for testing. |
| |
| // Write the WebApp data to disk and register the app. |
| virtual void FinalizeInstall(const WebAppInstallInfo& web_app_info, |
| const FinalizeOptions& options, |
| InstallFinalizedCallback callback); |
| |
| // Write the new WebApp data to disk and update the app. |
| // TODO(https://crbug.com/1196051): Chrome fails to update the manifest |
| // if the app window needing update closes at the same time as Chrome. |
| // Therefore, the manifest may not always update as expected. |
| virtual void FinalizeUpdate(const WebAppInstallInfo& web_app_info, |
| InstallFinalizedCallback callback); |
| |
| // Removes |webapp_uninstall_surface| from |app_id|. If no more interested |
| // sources left, deletes the app from disk and registrar. |
| virtual void UninstallExternalWebApp( |
| const AppId& app_id, |
| WebAppManagement::Type external_install_source, |
| webapps::WebappUninstallSource uninstall_surface, |
| UninstallWebAppCallback callback); |
| |
| // Removes the external app for |app_url| from disk and registrar. Fails if |
| // there is no installed external app for |app_url|. |
| virtual void UninstallExternalWebAppByUrl( |
| const GURL& app_url, |
| WebAppManagement::Type external_install_source, |
| webapps::WebappUninstallSource uninstall_surface, |
| UninstallWebAppCallback callback); |
| |
| // Removes |webapp_uninstall_surface| from |app_id|, no matter how many |
| // sources are left. |
| virtual void UninstallWebApp(const AppId& app_id, |
| webapps::WebappUninstallSource uninstall_surface, |
| UninstallWebAppCallback callback); |
| |
| virtual void RetryIncompleteUninstalls( |
| const base::flat_set<AppId>& apps_to_uninstall); |
| |
| // Sync-initiated uninstall. Copied from WebAppInstallSyncInstallDelegate. |
| // Called before the web apps are removed from the registry by sync. This: |
| // * Begins process of uninstalling OS hooks, which initially requires the |
| // registrar to still contain the web app data. |
| // * Notifies observers of WebAppWillBeUninstalled. |
| // After the app data is fully deleted & os hooks uninstalled: |
| // * Notifies observers of WebAppUninstalled. |
| // * `callback` is called. |
| // The registrar is expected to be synchronously updated after this function |
| // call to remove the given `web_apps`. |
| virtual void UninstallFromSync(const std::vector<AppId>& web_apps, |
| RepeatingUninstallCallback callback); |
| |
| virtual bool CanUserUninstallWebApp(const AppId& app_id) const; |
| |
| virtual bool CanReparentTab(const AppId& app_id, bool shortcut_created) const; |
| virtual void ReparentTab(const AppId& app_id, |
| bool shortcut_created, |
| content::WebContents* web_contents); |
| |
| void Start(); |
| void Shutdown(); |
| |
| void SetSubsystems(WebAppInstallManager* install_manager, |
| WebAppRegistrar* registrar, |
| WebAppUiManager* ui_manager, |
| WebAppSyncBridge* sync_bridge, |
| OsIntegrationManager* os_integration_manager, |
| WebAppIconManager* icon_manager, |
| WebAppPolicyManager* policy_manager, |
| WebAppTranslationManager* translation_manager); |
| |
| virtual void SetRemoveSourceCallbackForTesting( |
| base::RepeatingCallback<void(const AppId&)>); |
| |
| Profile* profile() { return profile_; } |
| |
| const WebAppRegistrar& GetWebAppRegistrar() const; |
| |
| // Writes external config data to the web_app DB, mapped per source. |
| void WriteExternalConfigMapInfo(WebApp& web_app, |
| WebAppManagement::Type source, |
| bool is_placeholder, |
| GURL install_url); |
| |
| std::vector<AppId> GetPendingUninstallsForTesting() const; |
| |
| private: |
| using CommitCallback = base::OnceCallback<void(bool success)>; |
| |
| void UninstallWebAppInternal(const AppId& app_id, |
| webapps::WebappUninstallSource uninstall_surface, |
| UninstallWebAppCallback callback); |
| void OnUninstallComplete(AppId app_id, |
| webapps::WebappUninstallSource uninstall_surface, |
| UninstallWebAppCallback callback, |
| webapps::UninstallResultCode code); |
| void UninstallExternalWebAppOrRemoveSource( |
| const AppId& app_id, |
| WebAppManagement::Type install_source, |
| webapps::WebappUninstallSource uninstall_surface, |
| UninstallWebAppCallback callback); |
| |
| void OnMaybeRegisterOsUninstall(const AppId& app_id, |
| WebAppManagement::Type source, |
| UninstallWebAppCallback callback, |
| OsHooksErrors os_hooks_errors); |
| |
| void SetWebAppManifestFieldsAndWriteData( |
| const WebAppInstallInfo& web_app_info, |
| std::unique_ptr<WebApp> web_app, |
| CommitCallback commit_callback); |
| |
| void WriteTranslations(const AppId& app_id, |
| const WebAppInstallInfo& web_app_info, |
| CommitCallback commit_callback, |
| bool success); |
| |
| void CommitToSyncBridge(std::unique_ptr<WebApp> web_app, |
| CommitCallback commit_callback, |
| bool success); |
| |
| void OnDatabaseCommitCompletedForInstall(InstallFinalizedCallback callback, |
| AppId app_id, |
| FinalizeOptions finalize_options, |
| bool success); |
| |
| void OnInstallHooksFinished(InstallFinalizedCallback callback, |
| AppId app_id, |
| web_app::OsHooksErrors os_hooks_errors); |
| void NotifyWebAppInstalledWithOsHooks(AppId app_id); |
| |
| bool ShouldUpdateOsHooks(const AppId& app_id); |
| |
| void OnDatabaseCommitCompletedForUpdate( |
| InstallFinalizedCallback callback, |
| AppId app_id, |
| std::string old_name, |
| FileHandlerUpdateAction file_handlers_need_os_update, |
| const WebAppInstallInfo& web_app_info, |
| bool success); |
| |
| void OnUpdateHooksFinished(InstallFinalizedCallback callback, |
| AppId app_id, |
| std::string old_name, |
| web_app::OsHooksErrors os_hooks_errors); |
| |
| // Returns a value indicating whether the file handlers registered with the OS |
| // should be updated. Used to avoid unnecessary updates. TODO(estade): why |
| // does this optimization exist when other OS hooks don't have similar |
| // optimizations? |
| FileHandlerUpdateAction GetFileHandlerUpdateAction( |
| const AppId& app_id, |
| const WebAppInstallInfo& new_web_app_info); |
| |
| raw_ptr<WebAppInstallManager> install_manager_ = nullptr; |
| raw_ptr<WebAppRegistrar> registrar_ = nullptr; |
| raw_ptr<WebAppSyncBridge> sync_bridge_ = nullptr; |
| raw_ptr<WebAppUiManager> ui_manager_ = nullptr; |
| raw_ptr<OsIntegrationManager> os_integration_manager_ = nullptr; |
| raw_ptr<WebAppIconManager> icon_manager_ = nullptr; |
| raw_ptr<WebAppPolicyManager> policy_manager_ = nullptr; |
| raw_ptr<WebAppTranslationManager> translation_manager_ = nullptr; |
| |
| const raw_ptr<Profile> profile_; |
| bool started_ = false; |
| |
| base::flat_map<AppId, std::unique_ptr<WebAppUninstallJob>> |
| pending_uninstalls_; |
| |
| base::RepeatingCallback<void(const AppId& app_id)> |
| install_source_removed_callback_for_testing_; |
| |
| base::WeakPtrFactory<WebAppInstallFinalizer> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace web_app |
| |
| #endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INSTALL_FINALIZER_H_ |