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
|
// Copyright (c) 2012 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_SHELL_INTEGRATION_H_
#define CHROME_BROWSER_SHELL_INTEGRATION_H_
#include <string>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
#include "ui/gfx/image/image_family.h"
#include "url/gurl.h"
namespace base {
class CommandLine;
}
namespace shell_integration {
// Sets Chrome as the default browser (only for the current user). Returns
// false if this operation fails.
bool SetAsDefaultBrowser();
// Initiates an OS shell flow which (if followed by the user) should set
// Chrome as the default browser. Returns false if the flow cannot be
// initialized, if it is not supported (introduced for Windows 8) or if the
// user cancels the operation. This is a blocking call and requires a FILE
// thread. If Chrome is already default browser, no interactive dialog will be
// shown and this method returns true.
bool SetAsDefaultBrowserInteractive();
// Sets Chrome as the default client application for the given protocol
// (only for the current user). Returns false if this operation fails.
bool SetAsDefaultProtocolClient(const std::string& protocol);
// Initiates an OS shell flow which (if followed by the user) should set
// Chrome as the default handler for |protocol|. Returns false if the flow
// cannot be initialized, if it is not supported (introduced for Windows 8)
// or if the user cancels the operation. This is a blocking call and requires
// a FILE thread. If Chrome is already default for |protocol|, no interactive
// dialog will be shown and this method returns true.
bool SetAsDefaultProtocolClientInteractive(const std::string& protocol);
// Windows 8 and Windows 10 introduced different ways to set the default
// browser.
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, Mac and Windows 7 and under.
SET_DEFAULT_UNATTENDED,
// On Windows 8, a browser can be made default only in an interactive flow.
SET_DEFAULT_INTERACTIVE,
};
// Returns requirements for making the running browser the user's default.
DefaultWebClientSetPermission CanSetAsDefaultBrowser();
// Returns requirements for making the running browser the user's default
// client application for specific protocols.
DefaultWebClientSetPermission CanSetAsDefaultProtocolClient();
// Returns true if making the running browser the default client for any
// protocol requires elevated privileges.
bool IsElevationNeededForSettingDefaultProtocolClient();
// Returns a string representing the application to be launched given the
// protocol 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.
base::string16 GetApplicationNameForProtocol(const GURL& url);
// On Linux, it may not be possible to determine or set the default browser
// on some desktop environments or configurations. So, we use this enum and
// not a plain bool.
enum DefaultWebClientState {
NOT_DEFAULT,
IS_DEFAULT,
UNKNOWN_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
// protocols; 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();
// Attempt to determine if this instance of Chrome is the default client
// application for the given protocol and return the appropriate state.
DefaultWebClientState IsDefaultProtocolClient(const std::string& protocol);
// Data that needs to be passed between the app launcher stub and Chrome.
struct AppModeInfo {};
void SetAppModeInfo(const AppModeInfo* info);
const AppModeInfo* AppModeInfo();
// 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);
// 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 defined(OS_WIN)
// Generates an application user model ID (AppUserModelId) for a given app
// name and profile path. The returned app id is in the format of
// "|app_name|[.<profile_id>]". "profile_id" is appended when user override
// the default value.
// Note: If the app has an installation specific suffix (e.g. on user-level
// Chrome installs), |app_name| should already be suffixed, this method will
// then further suffix it with the profile id as described above.
base::string16 GetAppModelIdForProfile(const base::string16& app_name,
const base::FilePath& profile_path);
// Generates an application user model ID (AppUserModelId) for Chromium by
// calling GetAppModelIdForProfile() with ShellUtil::GetAppId() as app_name.
base::string16 GetChromiumModelIdForProfile(const base::FilePath& profile_path);
// Get the AppUserModelId for the App List, for the profile in |profile_path|.
base::string16 GetAppListAppModelIdForProfile(
const base::FilePath& profile_path);
// Migrates existing chrome taskbar pins by tagging them with correct app id.
// see http://crbug.com/28104
void MigrateTaskbarPins();
// Migrates all shortcuts in |path| which point to |chrome_exe| such that they
// have the appropriate AppUserModelId. Also clears the legacy dual_mode
// property from shortcuts with the default chrome app id.
// Returns the number of shortcuts migrated.
// This method should not be called prior to Windows 7.
// This method is only public for the sake of tests and shouldn't be called
// externally otherwise.
int MigrateShortcutsInPathInternal(const base::FilePath& chrome_exe,
const base::FilePath& path);
// Returns the path to the Start Menu shortcut for the given Chrome.
base::FilePath GetStartMenuShortcut(const base::FilePath& chrome_exe);
#endif // defined(OS_WIN)
#if !defined(OS_WIN)
// TODO(calamity): replace with
// BrowserDistribution::GetStartMenuShortcutSubfolder() once
// BrowserDistribution is cross-platform.
// Gets the name of the Chrome Apps menu folder in which to place app
// shortcuts. This is needed for Mac and Linux.
base::string16 GetAppShortcutsSubdirName();
#endif
// The type of callback used to communicate processing state to consumers of
// DefaultBrowserWorker and DefaultProtocolClientWorker.
using DefaultWebClientWorkerCallback =
base::Callback<void(DefaultWebClientState)>;
// Helper objects that handle checking if Chrome is the default browser
// or application for a url protocol on Windows and Linux, and also setting
// it as the default. These operations are performed asynchronously on the
// file thread 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:
// 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
// instance's callback will be run to communicate the default state to the
// caller.
void StartCheckIsDefault();
// 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();
protected:
friend class base::RefCountedThreadSafe<DefaultWebClientWorker>;
DefaultWebClientWorker(const DefaultWebClientWorkerCallback& callback,
const char* worker_name);
virtual ~DefaultWebClientWorker();
// Communicates the result via the |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);
// 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 the
// FILE thread. 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);
// Sets Chrome as the default web client. Always called on the FILE thread.
void SetAsDefault();
// Implementation of CheckIsDefault() and SetAsDefault() for subclasses.
virtual DefaultWebClientState CheckIsDefaultImpl() = 0;
virtual void SetAsDefaultImpl() = 0;
// Reports the result for the set-as-default operation.
void ReportSetDefaultResult(DefaultWebClientState state);
// Updates the UI in our associated view with the current default web
// client state.
void UpdateUI(DefaultWebClientState state);
// Called with the default state after the worker is done.
DefaultWebClientWorkerCallback callback_;
// Used to differentiate UMA metrics for setting the default browser and
// setting the default protocol client. The pointer must be valid for the
// lifetime of the worker.
const char* worker_name_;
// Wait until Chrome has been confirmed as the default browser before
// reporting a successful attempt.
bool check_default_should_report_success_ = false;
DISALLOW_COPY_AND_ASSIGN(DefaultWebClientWorker);
};
// Worker for checking and setting the default browser.
class DefaultBrowserWorker : public DefaultWebClientWorker {
public:
explicit DefaultBrowserWorker(const DefaultWebClientWorkerCallback& callback);
private:
~DefaultBrowserWorker() override;
// Check if Chrome is the default browser.
DefaultWebClientState CheckIsDefaultImpl() override;
// Set Chrome as the default browser.
void SetAsDefaultImpl() override;
DISALLOW_COPY_AND_ASSIGN(DefaultBrowserWorker);
};
// Worker for checking and setting the default client application
// for a given protocol. A different worker instance is needed for each
// protocol you are interested in, so to check or set the default for
// multiple protocols you should use multiple worker objects.
class DefaultProtocolClientWorker : public DefaultWebClientWorker {
public:
DefaultProtocolClientWorker(const DefaultWebClientWorkerCallback& callback,
const std::string& protocol);
const std::string& protocol() const { return protocol_; }
protected:
~DefaultProtocolClientWorker() override;
private:
// Check if Chrome is the default handler for this protocol.
DefaultWebClientState CheckIsDefaultImpl() override;
// Set Chrome as the default handler for this protocol.
void SetAsDefaultImpl() override;
std::string protocol_;
DISALLOW_COPY_AND_ASSIGN(DefaultProtocolClientWorker);
};
} // namespace shell_integration
#endif // CHROME_BROWSER_SHELL_INTEGRATION_H_
|