// Copyright 2018 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_WEB_APP_SHORTCUT_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_OS_INTEGRATION_WEB_APP_SHORTCUT_H_ #include <memory> #include <set> #include <string> #include <vector> #include "base/files/file_path.h" #include "base/functional/callback_forward.h" #include "base/functional/callback_helpers.h" #include "base/sequence_checker.h" #include "build/build_config.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_install_info.h" #include "components/webapps/common/web_app_id.h" #include "ui/gfx/image/image_family.h" #include "url/gurl.h" #if BUILDFLAG(IS_LINUX) #include "chrome/browser/web_applications/os_integration/web_app_shortcut_linux.h" #endif // BUILDFLAG(IS_LINUX) #if BUILDFLAG(IS_MAC) #include "chrome/browser/web_applications/os_integration/mac/app_shim_registry.h" #endif class Profile; namespace base { class TaskRunner; class SequencedTaskRunner; } namespace gfx { class ImageSkia; } namespace web_app { namespace proto { class WebAppOsIntegrationState; class ShortcutMenus; } class WebApp; class WebAppIconManager; // Represents the info required to create a shortcut for an app. struct ShortcutInfo { … }; std::unique_ptr<ShortcutInfo> BuildShortcutInfoWithoutFavicon( const webapps::AppId& app_id, const GURL& start_url, const base::FilePath& profile_path, const std::string& profile_name, const proto::WebAppOsIntegrationState& state); void PopulateFaviconForShortcutInfo( const WebApp* app, WebAppIconManager& icon_manager, std::unique_ptr<ShortcutInfo> shortcut_info_to_populate, base::OnceCallback<void(std::unique_ptr<ShortcutInfo>)> callback); std::vector<WebAppShortcutsMenuItemInfo> CreateShortcutsMenuItemInfos( const proto::ShortcutMenus& shortcut_menus); // This specifies a folder in the system applications menu (e.g the Start Menu // on Windows). // // These represent the applications menu root, the "Google Chrome" folder and // the "Chrome Apps" folder respectively. // // APP_MENU_LOCATION_HIDDEN specifies a shortcut that is used to register the // app with the OS (in order to give its windows shelf icons, and correct icons // and titles), but the app should not show up in menus or search results. // // NB: On Linux, these locations may not be used by the window manager (e.g // Unity and Gnome Shell). enum ApplicationsMenuLocation { … }; // Info about which locations to create app shortcuts in. struct ShortcutLocations { … }; ShortcutLocations MergeLocations( const ShortcutLocations& user_specified_locations, const ShortcutLocations& existing_locations); bool operator==(const ShortcutLocations& location1, const ShortcutLocations& location2); bool operator!=(const ShortcutLocations& location1, const ShortcutLocations& location2); // This encodes the cause of shortcut creation as the correct behavior in each // case is implementation specific. enum ShortcutCreationReason { … }; // Compute a deterministic name based on data in the shortcut_info. std::string GenerateApplicationNameFromInfo(const ShortcutInfo& shortcut_info); // Returns a per-app directory for OS-specific web app data to handle OS // registration and unregistration. To store manifest resources, use // GetManifestResourcesDirectoryForApp() declared in web_app_utils.h. // // The path for the directory is based on |app_id|. If |app_id| is empty then // |url| is used to construct a unique ID. base::FilePath GetOsIntegrationResourcesDirectoryForApp( const base::FilePath& profile_path, const std::string& app_id, const GURL& url); // Callback made when CreateShortcuts has finished trying to create the // platform shortcuts indicating whether or not they were successfully // created. CreateShortcutsCallback; // Callback made when DeletePlatformShortcuts has finished trying to delete the // platform shortcuts indicating whether or not they were successfully // deleted. DeleteShortcutsCallback; // Returns an array of desired icon sizes (in px) to be contained in an app OS // shortcut, sorted in ascending order (biggest desired icon size is last). base::span<const int> GetDesiredIconSizesForShortcut(); // Load the standard application icon from resources. gfx::ImageSkia CreateDefaultApplicationIcon(int size); namespace internals { // Implemented for each platform, does the platform specific parts of creating // shortcuts. Used internally by CreateShortcuts methods. // |shortcut_data_path| is where to store any resources created for the // shortcut, and is also used as the UserDataDir for platform app shortcuts. // |creation_locations| contains information about where to create them. // |shortcut_info| contains info about the shortcut to create, and // |callback| must be called on the Shortcut IO thread when the work is // complete. // Performs blocking IO operations. void CreatePlatformShortcuts(const base::FilePath& shortcut_data_path, const ShortcutLocations& creation_locations, ShortcutCreationReason creation_reason, const ShortcutInfo& shortcut_info, CreateShortcutsCallback callback); // Implemented for each platform, does the platform specific parts of checking // desktop and application menu to get shortcut locations. ShortcutLocations GetAppExistingShortCutLocationImpl( const ShortcutInfo& shortcut_info); // Schedules a call to |CreatePlatformShortcuts| on the Shortcut IO thread and // invokes |callback| on the UI thread when complete. This function must be // called from the UI thread. void ScheduleCreatePlatformShortcuts( const base::FilePath& shortcut_data_path, const ShortcutLocations& creation_locations, ShortcutCreationReason reason, std::unique_ptr<ShortcutInfo> shortcut_info, CreateShortcutsCallback callback); void ScheduleDeletePlatformShortcuts( const base::FilePath& shortcut_data_path, std::unique_ptr<ShortcutInfo> shortcut_info, DeleteShortcutsCallback callback); // Schedules a call to `UpdatePlatformShortcuts` on the Shortcut IO thread and // invokes `callback` on the UI thread when complete. This function must be // called from the UI thread. void ScheduleUpdatePlatformShortcuts( const base::FilePath& shortcut_data_dir, const std::u16string& old_app_title, std::optional<ShortcutLocations> locations, base::OnceCallback<void(Result)> on_complete, std::unique_ptr<ShortcutInfo> shortcut_info); void ScheduleDeleteMultiProfileShortcutsForApp(const std::string& app_id, ResultCallback callback); // Delete all the shortcuts we have added for this extension, returning the // result via `callback` posted to `result_runner`. This is the platform // specific implementation of the DeleteAllShortcuts function, and is executed // on the FILE thread. void DeletePlatformShortcuts(const base::FilePath& shortcut_data_path, const ShortcutInfo& shortcut_info, scoped_refptr<base::TaskRunner> result_runner, DeleteShortcutsCallback callback); // Delete the multi-profile (non-profile_scoped) shortcuts for the specified // app. This is the multi-profile complement of DeletePlatformShortcuts. void DeleteMultiProfileShortcutsForApp(const std::string& app_id); // Updates all the shortcuts we have added for this extension. This is the // platform specific implementation of the UpdateAllShortcuts function, and // is executed on the FILE thread. On Windows, this also updates shortcuts in // the pinned taskbar directories. // If the |user_specified_locations| are set, then an union of the current // shortcut locations and the set values are considered during a shortcut // update. If a shortcut does not exist in a specific location, then that is // created. By default, the creation locations are not passed. // |callback| must be invoked on the Shortcut UI thread. Result::kOK will be // passed to the callback if the update was performed successfully, otherwise // Result::kError will be passed. void UpdatePlatformShortcuts( const base::FilePath& shortcut_data_path, const std::u16string& old_app_title, std::optional<ShortcutLocations> user_specified_locations, ResultCallback callback, const ShortcutInfo& shortcut_info); // Run an IO task on a worker thread. Ownership of |shortcut_info| transfers // to a closure that deletes it on the UI thread when the task is complete. // Tasks posted here run with BEST_EFFORT priority and block shutdown. void PostShortcutIOTask(base::OnceCallback<void(const ShortcutInfo&)> task, std::unique_ptr<ShortcutInfo> shortcut_info); void PostShortcutIOTaskAndReplyWithResult( base::OnceCallback<Result(const ShortcutInfo&)> task, std::unique_ptr<ShortcutInfo> shortcut_info, ResultCallback reply); // Run an IO task on a worker thread. Ownership of |shortcut_info| transfers // to the task which must delete it on the UI thread when the task is complete. // Tasks posted here run with BEST_EFFORT priority and block shutdown. void PostAsyncShortcutIOTask( base::OnceCallback<void(std::unique_ptr<ShortcutInfo>)> task, std::unique_ptr<ShortcutInfo> shortcut_info); // The task runner for running shortcut tasks. On Windows this will be a task // runner that permits access to COM libraries. Shortcut tasks typically deal // with ensuring Profile changes are reflected on disk, so shutdown is always // blocked so that an inconsistent shortcut state is not left on disk. scoped_refptr<base::SequencedTaskRunner> GetShortcutIOTaskRunner(); base::FilePath GetShortcutDataDir(const ShortcutInfo& shortcut_info); // Delete all the shortcuts for an entire profile. // This is executed on the FILE thread. void DeleteAllShortcutsForProfile(const base::FilePath& profile_path); } // namespace internals } // namespace web_app #endif // CHROME_BROWSER_WEB_APPLICATIONS_OS_INTEGRATION_WEB_APP_SHORTCUT_H_