1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
|
// Copyright 2012 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_SHELL_INTEGRATION_H_
#define CHROME_BROWSER_SHELL_INTEGRATION_H_
#include <map>
#include <string>
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/memory/ref_counted.h"
#include "build/build_config.h"
#include "url/gurl.h"
namespace base {
class CommandLine;
}
namespace shell_integration {
// Sets Chrome as the default browser (only for the current user).
//
// Don't use this, because:
// - This does not work on Windows version 8 or higher.
// - This cannot provide feedback as to success because setting a default
// browser is asynchronous.
//
// Use `DefaultBrowserWorker` instead.
// TODO(crbug.com/40248220): Extend `DefaultBrowserWorker` to work better
// on the Mac and remove this function.
bool SetAsDefaultBrowser();
// Sets Chrome as the default client application for the given scheme (only
// for the current user). Prefer to use the `DefaultSchemeClientWorker` class
// below since it works on all OSs.
//
// TODO(crbug.com/40248220): Extend `DefaultSchemeClientWorker` to work
// better on the Mac and remove this function.
bool SetAsDefaultClientForScheme(const std::string& scheme);
// The different types of permissions required to set a default web client.
enum DefaultWebClientSetPermission {
// The browser distribution is not permitted to be made default.
SET_DEFAULT_NOT_ALLOWED,
// No special permission or interaction is required to set the default
// browser. This is used in Linux and Windows 7 and under. This is returned
// for compatibility on the Mac, even though the Mac requires interaction.
// TODO(crbug.com/40248220): Fix this.
SET_DEFAULT_UNATTENDED,
// On the Mac and on Windows 8+, a browser can be made default only in an
// interactive flow. This value is returned for Windows 8+.
// TODO(crbug.com/40248220): Fix it so that this value is also returned
// on the Mac.
SET_DEFAULT_INTERACTIVE,
};
// Returns requirements for making the running browser the default browser.
DefaultWebClientSetPermission GetDefaultBrowserSetPermission();
// Returns requirements for making the running browser the default client
// application for specific schemes outside of the default browser.
DefaultWebClientSetPermission GetDefaultSchemeClientSetPermission();
// Returns true if the running browser can be set as the default browser,
// whether user interaction is needed or not. Use
// GetDefaultWebClientSetPermission() if this distinction is important.
bool CanSetAsDefaultBrowser();
// Returns a string representing the application to be launched given the
// scheme of the requested url. This string may be a name or a path, but
// neither is guaranteed and it should only be used as a display string.
// Returns an empty string on failure.
std::u16string GetApplicationNameForScheme(const GURL& url);
#if BUILDFLAG(IS_MAC)
// Returns a vector which containing all the application paths that can be used
// to launch the requested URL.
// Returns an empty vector if no application is found.
std::vector<base::FilePath> GetAllApplicationPathsForURL(const GURL& url);
// Returns true if the application at `path` can be used to launch the given
// `url`.
bool CanApplicationHandleURL(const base::FilePath& app_path, const GURL& url);
#endif
// Chrome's default web client state as a browser as a scheme client. If the
// current install mode is not default, the brand's other modes are
// checked. This allows callers to take specific action in case the current mode
// (e.g., Chrome Dev) is not the default handler, but another of the brand's
// modes (e.g., stable Chrome) is.
enum DefaultWebClientState {
// No install mode for the brand is the default client.
NOT_DEFAULT,
// The current install mode is the default client.
IS_DEFAULT,
// An error occurred while attempting to check the default client.
UNKNOWN_DEFAULT,
// The current install mode is not default, although one of the brand's
// other install modes is.
OTHER_MODE_IS_DEFAULT,
NUM_DEFAULT_STATES
};
// Attempt to determine if this instance of Chrome is the default browser and
// return the appropriate state. (Defined as being the handler for HTTP/HTTPS
// schemes; we don't want to report "no" here if the user has simply chosen
// to open HTML files in a text editor and FTP links with an FTP client.)
DefaultWebClientState GetDefaultBrowser();
// Returns true if Firefox is likely to be the default browser for the current
// user. This method is very fast so it can be invoked in the UI thread.
bool IsFirefoxDefaultBrowser();
#if BUILDFLAG(IS_WIN)
// Returns true if IE is likely to be the default browser for the current
// user. This method is very fast so it can be invoked in the UI thread.
bool IsIEDefaultBrowser();
// Returns the install id of the installation set as default browser. If no
// installation of Firefox is set as the default browser, returns an empty
// string.
std::string GetFirefoxProgIdSuffix();
#endif
// Attempt to determine if this instance of Chrome is the default client
// application for the given scheme and return the appropriate state.
DefaultWebClientState IsDefaultClientForScheme(const std::string& scheme);
#if BUILDFLAG(IS_WIN)
// Returns a `DefaultWebClientState` indicating whether this instance of Chrome
// is the default app for `file_extension`. `file_extension` must include a
// leading `.`, e.g., ".pdf".
DefaultWebClientState IsDefaultHandlerForFileExtension(
const std::string& file_extension);
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_MAC)
// Returns a `DefaultWebClientState` indicating whether this instance of Chrome
// is the default app for `type`. `type` must be a UTType identifier,
// e.g., "com.adobe.pdf".
DefaultWebClientState IsDefaultHandlerForUTType(const std::string& type);
// Sets Chrome as the default app for `type` (only for the current user). `type`
// must be a UTType identifier, e.g., "com.adobe.pdf".
bool SetAsDefaultHandlerForUTType(const std::string& type);
#endif // BUILDFLAG(IS_MAC)
// Is the current instance of Chrome running in App mode.
bool IsRunningInAppMode();
// Set up command line arguments for launching a URL or an app.
// The new command line reuses the current process's user data directory (and
// login profile, for ChromeOS).
// If |extension_app_id| is non-empty, the arguments use kAppId=<id>.
// Otherwise, kApp=<url> is used.
base::CommandLine CommandLineArgsForLauncher(
const GURL& url,
const std::string& extension_app_id,
const base::FilePath& profile_path,
const std::string& run_on_os_login_mode);
// Set up command line arguments for launching chrome at the given url using the
// given profile. All arguments must be non-empty and valid.
base::CommandLine CommandLineArgsForUrlShortcut(
const base::FilePath& chrome_exe_program,
const base::FilePath& profile_path,
const GURL& url);
// Append command line arguments for launching a new chrome.exe process
// based on the current process.
// The new command line reuses the current process's user data directory and
// profile.
void AppendProfileArgs(const base::FilePath& profile_path,
base::CommandLine* command_line);
#if !BUILDFLAG(IS_WIN)
// Gets the name of the Chrome Apps menu folder in which to place app
// shortcuts. This is needed for Mac and Linux.
std::u16string GetAppShortcutsSubdirName();
#endif
// The type of callback used to communicate processing state to consumers of
// DefaultBrowserWorker and DefaultSchemeClientWorker.
using DefaultWebClientWorkerCallback =
base::OnceCallback<void(DefaultWebClientState)>;
// The type of callback used to communicate processing state to consumers of
// DefaultBrowserWorker and DefaultSchemeClientWorker.
using DefaultSchemeHandlerWorkerCallback =
base::OnceCallback<void(DefaultWebClientState, const std::u16string&)>;
// Helper objects that handle checking if Chrome is the default browser
// or application for a url scheme on Windows and Linux, and also setting
// it as the default. These operations are performed asynchronously on a
// blocking sequence since registry access (on Windows) or the preference
// database (on Linux) are involved and this can be slow.
// By default, the worker will present the user with an interactive flow if
// required by the platform. This can be suppressed via
// set_interactive_permitted(), in which case an attempt to set Chrome as
// the default handler will silently fail on such platforms.
class DefaultWebClientWorker
: public base::RefCountedThreadSafe<DefaultWebClientWorker> {
public:
DefaultWebClientWorker(const DefaultWebClientWorker&) = delete;
DefaultWebClientWorker& operator=(const DefaultWebClientWorker&) = delete;
// Controls whether the worker can use user interaction to set the default
// web client. If false, the set-as-default operation will fail on OS where
// it is required.
void set_interactive_permitted(bool interactive_permitted) {
interactive_permitted_ = interactive_permitted;
}
// Checks to see if Chrome is the default web client application. The
// provided callback will be run to communicate the default state to the
// caller.
void StartCheckIsDefault(DefaultWebClientWorkerCallback callback);
// Sets Chrome as the default web client application. Once done, it will
// trigger a check for the default state using StartCheckIsDefault() to return
// the default state to the caller.
void StartSetAsDefault(DefaultWebClientWorkerCallback callback);
protected:
friend class base::RefCountedThreadSafe<DefaultWebClientWorker>;
explicit DefaultWebClientWorker(const char* worker_name);
virtual ~DefaultWebClientWorker();
// Communicates the result via |callback|. When
// |is_following_set_as_default| is true, |state| will be reported to UMA as
// the result of the set-as-default operation.
void OnCheckIsDefaultComplete(DefaultWebClientState state,
bool is_following_set_as_default,
DefaultWebClientWorkerCallback callback);
// When false, the operation to set as default will fail for interactive
// flows.
bool interactive_permitted_ = true;
private:
// Checks whether Chrome is the default web client. Always called on a
// blocking sequence. When |is_following_set_as_default| is true, The default
// state will be reported to UMA as the result of the set-as-default
// operation.
void CheckIsDefault(bool is_following_set_as_default,
DefaultWebClientWorkerCallback callback);
// Sets Chrome as the default web client. Always called on a blocking
// sequence.
void SetAsDefault(DefaultWebClientWorkerCallback callback);
// Implementation of CheckIsDefault() and SetAsDefault() for subclasses.
virtual DefaultWebClientState CheckIsDefaultImpl() = 0;
// The callback may be run synchronously or at an arbitrary time later on this
// thread.
// Note: Subclasses MUST make sure |on_finished_callback| is executed.
virtual void SetAsDefaultImpl(base::OnceClosure on_finished_callback) = 0;
// Reports the result for the set-as-default operation.
void ReportSetDefaultResult(DefaultWebClientState state);
// Used to differentiate UMA metrics for setting the default browser and
// setting the default scheme client. The pointer must be valid for the
// lifetime of the worker.
const char* worker_name_;
};
// Worker for checking and setting the default browser.
class DefaultBrowserWorker : public DefaultWebClientWorker {
public:
DefaultBrowserWorker();
DefaultBrowserWorker(const DefaultBrowserWorker&) = delete;
DefaultBrowserWorker& operator=(const DefaultBrowserWorker&) = delete;
static void DisableSetAsDefaultForTesting();
protected:
~DefaultBrowserWorker() override;
private:
// Check if Chrome is the default browser.
DefaultWebClientState CheckIsDefaultImpl() override;
// Set Chrome as the default browser.
void SetAsDefaultImpl(base::OnceClosure on_finished_callback) override;
static bool g_disable_set_as_default_for_testing;
};
// Worker for checking and setting the default client application
// for a given scheme. A different worker instance is needed for each
// scheme you are interested in, so to check or set the default for
// multiple scheme you should use multiple worker objects.
class DefaultSchemeClientWorker : public DefaultWebClientWorker {
public:
explicit DefaultSchemeClientWorker(const std::string& scheme);
explicit DefaultSchemeClientWorker(const GURL& url);
DefaultSchemeClientWorker(const DefaultSchemeClientWorker&) = delete;
DefaultSchemeClientWorker& operator=(const DefaultSchemeClientWorker&) =
delete;
// Checks to see if Chrome is the default application for the |url_|.
// The provided callback will be run to communicate the default state to the
// caller, and also return the name of the default client if available.
void StartCheckIsDefaultAndGetDefaultClientName(
DefaultSchemeHandlerWorkerCallback callback);
const std::string& scheme() const { return scheme_; }
const GURL& url() const { return url_; }
protected:
~DefaultSchemeClientWorker() override;
// Communicates the result via |callback|.
void OnCheckIsDefaultAndGetDefaultClientNameComplete(
DefaultWebClientState state,
std::u16string program_name,
DefaultSchemeHandlerWorkerCallback callback);
private:
// Checks whether Chrome is the default client for |url_|. This also returns
// the default client name if available.
void CheckIsDefaultAndGetDefaultClientName(
DefaultSchemeHandlerWorkerCallback callback);
// Check if Chrome is the default handler for this scheme.
DefaultWebClientState CheckIsDefaultImpl() override;
// Gets the default client name for |scheme_|. Always called on a blocking
// sequence.
virtual std::u16string GetDefaultClientNameImpl();
// Set Chrome as the default handler for this scheme.
void SetAsDefaultImpl(base::OnceClosure on_finished_callback) override;
const std::string scheme_;
const GURL url_;
};
namespace internal {
// The different ways to set the default web client.
enum class WebClientSetMethod {
// Method to set the default browser.
kDefaultBrowser,
// Method to set a default scheme handler outside of default browser.
kDefaultSchemeHandler,
};
// Returns requirements for making the running browser either the default
// browser or the default client application for specific schemes for the
// current user, according to a specific platform.
DefaultWebClientSetPermission GetPlatformSpecificDefaultWebClientSetPermission(
WebClientSetMethod method);
} // namespace internal
} // namespace shell_integration
#endif // CHROME_BROWSER_SHELL_INTEGRATION_H_
|