blob: 93cd23e85413c9a7d503ffe5981a15c45a6f28d1 [file] [log] [blame]
// 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_COMPONENTS_WEB_APP_SHORTCUT_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_SHORTCUT_H_
#include <memory>
#include <set>
#include <string>
#include "base/callback_forward.h"
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/sequence_checker.h"
#include "build/build_config.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/image/image_family.h"
#include "url/gurl.h"
namespace base {
class TaskRunner;
}
namespace gfx {
class ImageSkia;
}
namespace web_app {
struct ShortcutOverrideForTesting {
ShortcutOverrideForTesting(const ShortcutOverrideForTesting& other);
ShortcutOverrideForTesting();
~ShortcutOverrideForTesting();
#if defined(OS_WIN)
base::FilePath desktop;
base::FilePath application_menu;
base::FilePath quick_launch;
base::FilePath startup;
#elif defined(OS_MAC)
base::FilePath chrome_apps_folder;
#elif defined(OS_LINUX)
base::FilePath desktop;
#else
#endif
};
absl::optional<ShortcutOverrideForTesting>& GetShortcutOverrideForTesting();
void SetShortcutOverrideForTesting(
absl::optional<ShortcutOverrideForTesting> shortcut_override_for_testing);
// Represents the info required to create a shortcut for an app.
struct ShortcutInfo {
ShortcutInfo();
ShortcutInfo(const ShortcutInfo&) = delete;
ShortcutInfo& operator=(const ShortcutInfo&) = delete;
~ShortcutInfo();
GURL url;
// If |extension_id| is non-empty, this is short cut is to an extension-app
// and the launch url will be detected at start-up. In this case, |url|
// is still used to generate the app id (windows app id, not chrome app id).
// TODO(loyso): Rename it to app_id.
std::string extension_id;
std::u16string title;
std::u16string description;
gfx::ImageFamily favicon;
base::FilePath profile_path;
std::string profile_name;
std::string version_for_display;
std::set<std::string> file_handler_extensions;
std::set<std::string> file_handler_mime_types;
std::set<std::string> protocol_handlers;
// An app is multi-profile if there is a single shortcut and single app shim
// for all profiles. The app itself has a profile switcher that may be used
// to open windows for the various profiles. This is relevant only on macOS.
bool is_multi_profile = false;
private:
// Since gfx::ImageFamily |favicon| has a non-thread-safe reference count in
// its member and is bound to current thread, always destroy ShortcutInfo
// instance on the same thread.
SEQUENCE_CHECKER(sequence_checker_);
};
// 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 {
APP_MENU_LOCATION_NONE,
APP_MENU_LOCATION_SUBDIR_CHROMEAPPS,
APP_MENU_LOCATION_HIDDEN,
};
// Info about which locations to create app shortcuts in.
struct ShortcutLocations {
bool on_desktop = false;
ApplicationsMenuLocation applications_menu_location = APP_MENU_LOCATION_NONE;
// For Windows, this refers to quick launch bar prior to Win7. In Win7,
// this means "pin to taskbar". For Mac/Linux, this could be used for
// Mac dock or the gnome/kde application launcher. However, those are not
// implemented yet.
bool in_quick_launch_bar = false;
// For Windows, this refers to the Startup folder.
// For Mac, this refers to the Login Items list.
// For Linux, this refers to the autostart folder.
bool in_startup = false;
};
// This encodes the cause of shortcut creation as the correct behavior in each
// case is implementation specific.
enum ShortcutCreationReason {
SHORTCUT_CREATION_BY_USER,
SHORTCUT_CREATION_AUTOMATED,
};
// 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.
using CreateShortcutsCallback = base::OnceCallback<void(bool shortcut_created)>;
// Callback made when DeletePlatformShortcuts has finished trying to delete the
// platform shortcuts indicating whether or not they were successfully
// deleted.
using DeleteShortcutsCallback = base::OnceCallback<void(bool shortcut_deleted)>;
// 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.
// |shortcut_info| contains info about the shortcut to create, and
// |creation_locations| contains information about where to create them.
// Performs blocking IO operations.
bool CreatePlatformShortcuts(const base::FilePath& shortcut_data_path,
const ShortcutLocations& creation_locations,
ShortcutCreationReason creation_reason,
const ShortcutInfo& shortcut_info);
// 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| 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);
void ScheduleDeleteMultiProfileShortcutsForApp(
const std::string& app_id,
DeleteShortcutsCallback callback);
// Delete all the shortcuts we have added for this extension. This is the
// platform specific implementation of the DeleteAllShortcuts function, and
// is executed on the FILE thread.
bool DeletePlatformShortcuts(const base::FilePath& shortcut_data_path,
const ShortcutInfo& shortcut_info);
// 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.
void UpdatePlatformShortcuts(const base::FilePath& shortcut_data_path,
const std::u16string& old_app_title,
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 PostShortcutIOTaskAndReply(
base::OnceCallback<void(const ShortcutInfo&)> task,
std::unique_ptr<ShortcutInfo> shortcut_info,
base::OnceClosure reply);
// 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::TaskRunner> 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_COMPONENTS_WEB_APP_SHORTCUT_H_