| // Copyright 2020 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_OS_INTEGRATION_OS_INTEGRATION_MANAGER_H_ |
| #define CHROME_BROWSER_WEB_APPLICATIONS_OS_INTEGRATION_OS_INTEGRATION_MANAGER_H_ |
| |
| #include <bitset> |
| #include <memory> |
| #include <vector> |
| |
| #include "base/auto_reset.h" |
| #include "base/callback_forward.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/scoped_observation.h" |
| #include "base/strings/string_piece_forward.h" |
| #include "chrome/browser/web_applications/app_registrar_observer.h" |
| #include "chrome/browser/web_applications/os_integration/url_handler_manager.h" |
| #include "chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h" |
| #include "chrome/browser/web_applications/os_integration/web_app_protocol_handler_manager.h" |
| #include "chrome/browser/web_applications/os_integration/web_app_run_on_os_login.h" |
| #include "chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h" |
| #include "chrome/browser/web_applications/proto/web_app_os_integration_state.pb.h" |
| #include "chrome/browser/web_applications/web_app.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 "components/custom_handlers/protocol_handler.h" |
| #include "components/services/app_service/public/cpp/file_handler.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| class Profile; |
| |
| namespace web_app { |
| |
| class FakeOsIntegrationManager; |
| class WebAppIconManager; |
| class WebAppRegistrar; |
| class WebAppSyncBridge; |
| class OsIntegrationSubManager; |
| class WebAppUiManager; |
| |
| // OsHooksErrors contains the result of all Os hook deployments. |
| // If a bit is set to `true`, then an error did occur. |
| using OsHooksErrors = std::bitset<OsHookType::kMaxValue + 1>; |
| |
| // OsHooksOptions contains the (install/uninstall) options of all Os hook |
| // deployments. |
| using OsHooksOptions = std::bitset<OsHookType::kMaxValue + 1>; |
| |
| // Used to pass install options configured from upstream caller. |
| // All options are disabled by default. |
| struct InstallOsHooksOptions { |
| InstallOsHooksOptions(); |
| InstallOsHooksOptions(const InstallOsHooksOptions& other); |
| InstallOsHooksOptions& operator=(const InstallOsHooksOptions& other); |
| |
| OsHooksOptions os_hooks; |
| bool add_to_desktop = false; |
| bool add_to_quick_launch_bar = false; |
| ShortcutCreationReason reason = SHORTCUT_CREATION_BY_USER; |
| }; |
| |
| // Retire these 3 once the sub-manager project is done. |
| // Callback made after InstallOsHooks is finished. |
| using InstallOsHooksCallback = |
| base::OnceCallback<void(OsHooksErrors os_hooks_errors)>; |
| |
| // Callback made after UninstallOsHooks is finished. |
| using UninstallOsHooksCallback = |
| base::OnceCallback<void(OsHooksErrors os_hooks_errors)>; |
| |
| // Callback made after UpdateOsHooks is finished. |
| using UpdateOsHooksCallback = |
| base::OnceCallback<void(OsHooksErrors os_hooks_errors)>; |
| |
| using BarrierCallback = |
| base::RepeatingCallback<void(OsHookType::Type os_hook, bool completed)>; |
| |
| // OsIntegrationManager is responsible of creating/updating/deleting |
| // all OS hooks during Web App lifecycle. |
| // It contains individual OS integration managers and takes |
| // care of inter-dependencies among them. |
| class OsIntegrationManager : public AppRegistrarObserver { |
| public: |
| // Used to suppress OS hooks during this object's lifetime. |
| class ScopedSuppressForTesting { |
| public: |
| ScopedSuppressForTesting(); |
| ~ScopedSuppressForTesting(); |
| |
| private: |
| base::AutoReset<bool> scope_; |
| }; |
| |
| explicit OsIntegrationManager( |
| Profile* profile, |
| std::unique_ptr<WebAppShortcutManager> shortcut_manager, |
| std::unique_ptr<WebAppFileHandlerManager> file_handler_manager, |
| std::unique_ptr<WebAppProtocolHandlerManager> protocol_handler_manager, |
| std::unique_ptr<UrlHandlerManager> url_handler_manager); |
| ~OsIntegrationManager() override; |
| |
| using AnyOsHooksErrorCallback = |
| base::OnceCallback<void(OsHooksErrors os_hooks_errors)>; |
| static base::RepeatingCallback<void(OsHooksErrors)> GetBarrierForSynchronize( |
| AnyOsHooksErrorCallback errors_callback); |
| |
| virtual void SetSubsystems(WebAppSyncBridge* sync_bridge, |
| WebAppRegistrar* registrar, |
| WebAppUiManager* ui_manager, |
| WebAppIconManager* icon_manager); |
| |
| virtual void Start(); |
| |
| // Start OS Integration synchronization from external callsites. This should |
| // be the only point of call into OsIntegrationManager from external places |
| // after the OS integration sub managers have been implemented. |
| // TODO(crbug.com/1401125): Remove all install, uninstall and update functions |
| // from this file once all OS Integration sub managers have been implemented, |
| // connected to the web_app system and tested. |
| virtual void Synchronize(const AppId& app_id, base::OnceClosure callback); |
| |
| // Install all needed OS hooks for the web app. |
| // If provided |web_app_info| is a nullptr, it will read icons data from disk, |
| // otherwise it will use (SkBitmaps) from |web_app_info|. |
| // virtual for testing |
| virtual void InstallOsHooks(const AppId& app_id, |
| InstallOsHooksCallback callback, |
| std::unique_ptr<WebAppInstallInfo> web_app_info, |
| InstallOsHooksOptions options); |
| |
| // Uninstall specific OS hooks for the web app. |
| // Used when removing specific hooks resulting from an app setting change. |
| // Example: Running on OS login. |
| // TODO(https://crbug.com/1108109) we should record uninstall result and allow |
| // callback. virtual for testing |
| virtual void UninstallOsHooks(const AppId& app_id, |
| const OsHooksOptions& os_hooks, |
| UninstallOsHooksCallback callback); |
| |
| // Uninstall all OS hooks for the web app. |
| // Used when uninstalling a web app. |
| // virtual for testing |
| virtual void UninstallAllOsHooks(const AppId& app_id, |
| UninstallOsHooksCallback callback); |
| |
| // Update all needed OS hooks for the web app. |
| // virtual for testing |
| virtual void UpdateOsHooks( |
| const AppId& app_id, |
| base::StringPiece old_name, |
| FileHandlerUpdateAction file_handlers_need_os_update, |
| const WebAppInstallInfo& web_app_info, |
| UpdateOsHooksCallback callback); |
| |
| // Proxy calls for WebAppShortcutManager. |
| // virtual for testing |
| virtual void GetAppExistingShortCutLocation( |
| ShortcutLocationCallback callback, |
| std::unique_ptr<ShortcutInfo> shortcut_info); |
| |
| // Proxy calls for WebAppShortcutManager. |
| void GetShortcutInfoForApp( |
| const AppId& app_id, |
| WebAppShortcutManager::GetShortcutInfoCallback callback); |
| |
| // Proxy calls for WebAppFileHandlerManager. |
| bool IsFileHandlingAPIAvailable(const AppId& app_id); |
| const apps::FileHandlers* GetEnabledFileHandlers(const AppId& app_id) const; |
| |
| // Proxy calls for WebAppProtocolHandlerManager. |
| virtual absl::optional<GURL> TranslateProtocolUrl(const AppId& app_id, |
| const GURL& protocol_url); |
| virtual std::vector<custom_handlers::ProtocolHandler> GetAppProtocolHandlers( |
| const AppId& app_id); |
| virtual std::vector<custom_handlers::ProtocolHandler> |
| GetAllowedHandlersForProtocol(const std::string& protocol); |
| virtual std::vector<custom_handlers::ProtocolHandler> |
| GetDisallowedHandlersForProtocol(const std::string& protocol); |
| |
| WebAppFileHandlerManager& file_handler_manager() { |
| return *file_handler_manager_; |
| } |
| |
| WebAppShortcutManager& shortcut_manager_for_testing(); |
| |
| UrlHandlerManager& url_handler_manager_for_testing(); |
| |
| WebAppProtocolHandlerManager& protocol_handler_manager_for_testing(); |
| |
| virtual FakeOsIntegrationManager* AsTestOsIntegrationManager(); |
| |
| void set_url_handler_manager( |
| std::unique_ptr<UrlHandlerManager> url_handler_manager) { |
| url_handler_manager_ = std::move(url_handler_manager); |
| } |
| |
| virtual void UpdateUrlHandlers( |
| const AppId& app_id, |
| base::OnceCallback<void(bool success)> callback); |
| |
| virtual void UpdateFileHandlers( |
| const AppId& app_id, |
| FileHandlerUpdateAction file_handlers_need_os_update, |
| ResultCallback finished_callback); |
| |
| // Updates protocol handler registrations with the OS. |
| // If `force_shortcut_updates_if_needed` is true, then also update the |
| // application's shortcuts. |
| virtual void UpdateProtocolHandlers(const AppId& app_id, |
| bool force_shortcut_updates_if_needed, |
| base::OnceClosure callback); |
| |
| virtual void UpdateShortcuts(const AppId& app_id, |
| base::StringPiece old_name, |
| ResultCallback callback); |
| |
| // AppRegistrarObserver: |
| void OnWebAppProfileWillBeDeleted(const AppId& app_id) override; |
| void OnAppRegistrarDestroyed() override; |
| |
| protected: |
| WebAppShortcutManager* shortcut_manager() { return shortcut_manager_.get(); } |
| WebAppProtocolHandlerManager* protocol_handler_manager() { |
| return protocol_handler_manager_.get(); |
| } |
| UrlHandlerManager* url_handler_manager() { |
| return url_handler_manager_.get(); |
| } |
| void set_shortcut_manager( |
| std::unique_ptr<WebAppShortcutManager> shortcut_manager) { |
| shortcut_manager_ = std::move(shortcut_manager); |
| } |
| bool has_file_handler_manager() { return !!file_handler_manager_; } |
| void set_file_handler_manager( |
| std::unique_ptr<WebAppFileHandlerManager> file_handler_manager) { |
| file_handler_manager_ = std::move(file_handler_manager); |
| } |
| void set_protocol_handler_manager( |
| std::unique_ptr<WebAppProtocolHandlerManager> protocol_handler_manager) { |
| protocol_handler_manager_ = std::move(protocol_handler_manager); |
| } |
| |
| virtual void CreateShortcuts(const AppId& app_id, |
| bool add_to_desktop, |
| ShortcutCreationReason reason, |
| CreateShortcutsCallback callback); |
| |
| // Installation: |
| virtual void RegisterFileHandlers(const AppId& app_id, |
| ResultCallback callback); |
| virtual void RegisterProtocolHandlers(const AppId& app_id, |
| ResultCallback callback); |
| virtual void RegisterUrlHandlers(const AppId& app_id, |
| ResultCallback callback); |
| virtual void RegisterShortcutsMenu( |
| const AppId& app_id, |
| const std::vector<WebAppShortcutsMenuItemInfo>& shortcuts_menu_item_infos, |
| const ShortcutsMenuIconBitmaps& shortcuts_menu_icon_bitmaps, |
| ResultCallback callback); |
| virtual void ReadAllShortcutsMenuIconsAndRegisterShortcutsMenu( |
| const AppId& app_id, |
| ResultCallback callback); |
| virtual void RegisterRunOnOsLogin(const AppId& app_id, |
| ResultCallback callback); |
| virtual void MacAppShimOnAppInstalledForProfile(const AppId& app_id); |
| virtual void AddAppToQuickLaunchBar(const AppId& app_id); |
| virtual void RegisterWebAppOsUninstallation(const AppId& app_id, |
| const std::string& name); |
| |
| // Uninstallation: |
| virtual bool UnregisterShortcutsMenu(const AppId& app_id, |
| ResultCallback callback); |
| virtual void UnregisterRunOnOsLogin(const AppId& app_id, |
| ResultCallback callback); |
| virtual void DeleteShortcuts(const AppId& app_id, |
| const base::FilePath& shortcuts_data_dir, |
| std::unique_ptr<ShortcutInfo> shortcut_info, |
| ResultCallback callback); |
| virtual void UnregisterFileHandlers(const AppId& app_id, |
| ResultCallback callback); |
| virtual void UnregisterProtocolHandlers(const AppId& app_id, |
| ResultCallback callback); |
| virtual void UnregisterUrlHandlers(const AppId& app_id); |
| virtual void UnregisterWebAppOsUninstallation(const AppId& app_id); |
| |
| // Update: |
| virtual void UpdateShortcutsMenu(const AppId& app_id, |
| const WebAppInstallInfo& web_app_info, |
| ResultCallback callback); |
| |
| // Utility methods: |
| virtual std::unique_ptr<ShortcutInfo> BuildShortcutInfo(const AppId& app_id); |
| |
| private: |
| class OsHooksBarrier; |
| |
| virtual void ExecuteAllSubManagerConfigurations( |
| const AppId& app_id, |
| std::unique_ptr<proto::WebAppOsIntegrationState> desired_states, |
| base::OnceClosure callback); |
| |
| virtual void WriteStateToDB( |
| const AppId& app_id, |
| std::unique_ptr<proto::WebAppOsIntegrationState> desired_states, |
| base::OnceClosure callback); |
| |
| void OnShortcutsCreated(const AppId& app_id, |
| std::unique_ptr<WebAppInstallInfo> web_app_info, |
| InstallOsHooksOptions options, |
| scoped_refptr<OsHooksBarrier> barrier, |
| bool shortcuts_created); |
| |
| void OnShortcutsDeleted(const AppId& app_id, |
| ResultCallback callback, |
| Result result); |
| |
| void OnShortcutInfoRetrievedRegisterRunOnOsLogin( |
| ResultCallback callback, |
| std::unique_ptr<ShortcutInfo> info); |
| |
| // Called after the shortcuts for an app are updated in response |
| // to protocol handler changes. |
| // `update_finished_callback` is the callback provided in |
| // `UpdateProtocolHandlers`. |
| void OnShortcutsUpdatedForProtocolHandlers( |
| const AppId& app_id, |
| base::OnceClosure update_finished_callback); |
| |
| const raw_ptr<Profile> profile_; |
| raw_ptr<WebAppRegistrar> registrar_ = nullptr; |
| raw_ptr<WebAppUiManager> ui_manager_ = nullptr; |
| raw_ptr<WebAppSyncBridge> sync_bridge_ = nullptr; |
| |
| std::unique_ptr<WebAppShortcutManager> shortcut_manager_; |
| std::unique_ptr<WebAppFileHandlerManager> file_handler_manager_; |
| std::unique_ptr<WebAppProtocolHandlerManager> protocol_handler_manager_; |
| std::unique_ptr<UrlHandlerManager> url_handler_manager_; |
| |
| std::vector<std::unique_ptr<OsIntegrationSubManager>> sub_managers_; |
| |
| base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver> |
| registrar_observation_{this}; |
| |
| base::WeakPtrFactory<OsIntegrationManager> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace web_app |
| |
| #endif // CHROME_BROWSER_WEB_APPLICATIONS_OS_INTEGRATION_OS_INTEGRATION_MANAGER_H_ |