OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_SHELL_INTEGRATION_H_ | 5 #ifndef CHROME_BROWSER_SHELL_INTEGRATION_H_ |
6 #define CHROME_BROWSER_SHELL_INTEGRATION_H_ | 6 #define CHROME_BROWSER_SHELL_INTEGRATION_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/strings/string16.h" | 13 #include "base/strings/string16.h" |
14 #include "base/timer/timer.h" | |
14 #include "ui/gfx/image/image_family.h" | 15 #include "ui/gfx/image/image_family.h" |
15 #include "url/gurl.h" | 16 #include "url/gurl.h" |
16 | 17 |
17 namespace base { | 18 namespace base { |
18 class CommandLine; | 19 class CommandLine; |
19 } | 20 } |
20 | 21 |
21 class ShellIntegration { | 22 class ShellIntegration { |
22 public: | 23 public: |
23 // Sets Chrome as the default browser (only for the current user). Returns | 24 // Sets Chrome as the default browser (only for the current user). Returns |
24 // false if this operation fails. | 25 // false if this operation fails. |
25 static bool SetAsDefaultBrowser(); | 26 static bool SetAsDefaultBrowser(); |
26 | 27 |
27 // Initiates an OS shell flow which (if followed by the user) should set | 28 // Initiates an OS shell flow which (if followed by the user) should set |
28 // Chrome as the default browser. Returns false if the flow cannot be | 29 // Chrome as the default browser. Returns false if the flow cannot be |
29 // initialized, if it is not supported (introduced for Windows 8) or if the | 30 // initialized, if it is not supported (introduced for Windows 8) or if the |
30 // user cancels the operation. This is a blocking call and requires a FILE | 31 // user cancels the operation. This is a blocking call and requires a FILE |
31 // thread. If Chrome is already default browser, no interactive dialog will be | 32 // thread. If Chrome is already default browser, no interactive dialog will be |
32 // shown and this method returns true. | 33 // shown and this method returns true. |
33 static bool SetAsDefaultBrowserInteractive(); | 34 static bool SetAsDefaultBrowserInteractive(); |
34 | 35 |
36 // Returns true if setting the default browser is an asynchronous operation. | |
37 // In practice, this is only true on Windows 10+. | |
38 static bool IsSetAsDefaultAsynchronous(); | |
39 | |
40 // Prompt the user to select the default browser by trying to open | |
41 // https://support.google.com/chrome?p=default_browser which is the "How to | |
42 // set Chrome as your default browser" help page. Only call this if | |
43 // |IsSetAsDefaultAsynchronous| is true. | |
44 // | |
45 // The caller should add an URL filter to intercept the link navigation (See | |
46 // startup_browser_creator.h). | |
47 // The caller should also set up a timer to represent an unsuccessful attempt | |
48 // after a certain amount of time. | |
49 static void SetAsDefaultBrowserAsynchronous(); | |
50 | |
35 // Sets Chrome as the default client application for the given protocol | 51 // Sets Chrome as the default client application for the given protocol |
36 // (only for the current user). Returns false if this operation fails. | 52 // (only for the current user). Returns false if this operation fails. |
37 static bool SetAsDefaultProtocolClient(const std::string& protocol); | 53 static bool SetAsDefaultProtocolClient(const std::string& protocol); |
38 | 54 |
39 // Initiates an OS shell flow which (if followed by the user) should set | 55 // Initiates an OS shell flow which (if followed by the user) should set |
40 // Chrome as the default handler for |protocol|. Returns false if the flow | 56 // Chrome as the default handler for |protocol|. Returns false if the flow |
41 // cannot be initialized, if it is not supported (introduced for Windows 8) | 57 // cannot be initialized, if it is not supported (introduced for Windows 8) |
42 // or if the user cancels the operation. This is a blocking call and requires | 58 // or if the user cancels the operation. This is a blocking call and requires |
43 // a FILE thread. If Chrome is already default for |protocol|, no interactive | 59 // a FILE thread. If Chrome is already default for |protocol|, no interactive |
44 // dialog will be shown and this method returns true. | 60 // dialog will be shown and this method returns true. |
45 static bool SetAsDefaultProtocolClientInteractive( | 61 static bool SetAsDefaultProtocolClientInteractive( |
46 const std::string& protocol); | 62 const std::string& protocol); |
47 | 63 |
48 // In Windows 8 a browser can be made default-in-metro only in an interactive | 64 // In Windows 8 a browser can be made default-in-metro only in an interactive |
grt (UTC plus 2)
2015/09/22 18:21:47
please update comment with a note about Win10 usin
Patrick Monette
2015/09/23 22:40:44
Done.
| |
49 // flow. We will distinguish between two types of permissions here to avoid | 65 // flow. We will distinguish between two types of permissions here to avoid |
50 // forcing the user into UI interaction when this should not be done. | 66 // forcing the user into UI interaction when this should not be done. |
51 enum DefaultWebClientSetPermission { | 67 enum DefaultWebClientSetPermission { |
52 SET_DEFAULT_NOT_ALLOWED, | 68 SET_DEFAULT_NOT_ALLOWED, |
53 SET_DEFAULT_UNATTENDED, | 69 SET_DEFAULT_UNATTENDED, |
54 SET_DEFAULT_INTERACTIVE, | 70 SET_DEFAULT_INTERACTIVE, |
71 SET_DEFAULT_ASYNCHRONOUS, | |
55 }; | 72 }; |
56 | 73 |
57 // Returns requirements for making the running browser the user's default. | 74 // Returns requirements for making the running browser the user's default. |
58 static DefaultWebClientSetPermission CanSetAsDefaultBrowser(); | 75 static DefaultWebClientSetPermission CanSetAsDefaultBrowser(); |
59 | 76 |
60 // Returns requirements for making the running browser the user's default | 77 // Returns requirements for making the running browser the user's default |
61 // client application for specific protocols. | 78 // client application for specific protocols. |
62 static DefaultWebClientSetPermission CanSetAsDefaultProtocolClient(); | 79 static DefaultWebClientSetPermission CanSetAsDefaultProtocolClient(); |
63 | 80 |
64 // Returns true if making the running browser the default client for any | 81 // Returns true if making the running browser the default client for any |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 // An observer can permit or decline set-as-default operation if it | 213 // An observer can permit or decline set-as-default operation if it |
197 // requires triggering user interaction. By default not allowed. | 214 // requires triggering user interaction. By default not allowed. |
198 virtual bool IsInteractiveSetDefaultPermitted(); | 215 virtual bool IsInteractiveSetDefaultPermitted(); |
199 }; | 216 }; |
200 | 217 |
201 // Helper objects that handle checking if Chrome is the default browser | 218 // Helper objects that handle checking if Chrome is the default browser |
202 // or application for a url protocol on Windows and Linux, and also setting | 219 // or application for a url protocol on Windows and Linux, and also setting |
203 // it as the default. These operations are performed asynchronously on the | 220 // it as the default. These operations are performed asynchronously on the |
204 // file thread since registry access (on Windows) or the preference database | 221 // file thread since registry access (on Windows) or the preference database |
205 // (on Linux) are involved and this can be slow. | 222 // (on Linux) are involved and this can be slow. |
223 // | |
224 // On windows 10+, there is no official way to prompt the user to set a | |
grt (UTC plus 2)
2015/09/22 18:21:47
this seems like an implementation detail that cons
Patrick Monette
2015/09/23 22:40:44
Done.
| |
225 // default browser. This is the workaround: | |
226 // 1. Unregister the default browser. | |
227 // 2. Open "How to make Chrome my default browser" link with ShellExecute. | |
228 // 3. Windows prompt the user with "How would you link to open this?". | |
229 // 4. If Chrome is selected, the http url is intercepted and | |
230 // CompleteSetAsDefault is called with succeeded equals to true. | |
231 // 5. If Chrome is not selected, the url is opened in the selected browser. | |
232 // After a certain amount of time, we notify the observer that the | |
233 // process failed. | |
206 class DefaultWebClientWorker | 234 class DefaultWebClientWorker |
207 : public base::RefCountedThreadSafe<DefaultWebClientWorker> { | 235 : public base::RefCountedThreadSafe<DefaultWebClientWorker> { |
208 public: | 236 public: |
209 explicit DefaultWebClientWorker(DefaultWebClientObserver* observer); | 237 explicit DefaultWebClientWorker(DefaultWebClientObserver* observer); |
210 | 238 |
211 // Checks to see if Chrome is the default web client application. The result | 239 // Checks to see if Chrome is the default web client application. The result |
212 // will be passed back to the observer via the SetDefaultWebClientUIState | 240 // will be passed back to the observer via the SetDefaultWebClientUIState |
213 // function. If there is no observer, this function does not do anything. | 241 // function. If there is no observer, this function does not do anything. |
214 void StartCheckIsDefault(); | 242 void StartCheckIsDefault(); |
215 | 243 |
216 // Sets Chrome as the default web client application. If there is an | 244 // Sets Chrome as the default web client application. If there is an |
217 // observer, once the operation has completed the new default will be | 245 // observer, once the operation has completed the new default will be |
218 // queried and the current status reported via SetDefaultWebClientUIState. | 246 // queried and the current status reported via SetDefaultWebClientUIState. |
219 void StartSetAsDefault(); | 247 void StartSetAsDefault(); |
220 | 248 |
221 // Called to notify the worker that the view is gone. | 249 // Called to notify the worker that the view is gone. |
222 void ObserverDestroyed(); | 250 void ObserverDestroyed(); |
223 | 251 |
224 protected: | 252 protected: |
225 friend class base::RefCountedThreadSafe<DefaultWebClientWorker>; | 253 friend class base::RefCountedThreadSafe<DefaultWebClientWorker>; |
226 | 254 |
227 virtual ~DefaultWebClientWorker() {} | 255 virtual ~DefaultWebClientWorker() {} |
228 | 256 |
257 // When the action to set Chrome as the default has completed this function | |
258 // is run. This function will call UninitializeSetAsDefault and then start | |
259 // the check process, which, if an observer is present, reports to it the | |
260 // new status. |succeeded| is true if the actual call to a set-default | |
261 // function (from ExecuteSetAsDefault) was successful. | |
262 void CompleteSetAsDefault(bool succeeded); | |
263 | |
264 #if defined(OS_WIN) | |
grt (UTC plus 2)
2015/09/22 18:21:47
move these into the private: block at the bottom o
grt (UTC plus 2)
2015/09/22 19:17:48
actually, it looks like they can be among DefaultB
Patrick Monette
2015/09/23 22:40:44
Done.
| |
265 // Used to determine if setting the default browser was unsuccesful. | |
266 scoped_ptr<base::OneShotTimer<DefaultWebClientWorker>> async_timer_; | |
267 | |
268 // Records the time it takes to set the default browser asynchronously. | |
269 base::TimeTicks start_time_; | |
270 #endif // !defined(OS_WIN) | |
271 | |
229 private: | 272 private: |
230 // Function that performs the check. | 273 // Function that performs the check. |
231 virtual DefaultWebClientState CheckIsDefault() = 0; | 274 virtual DefaultWebClientState CheckIsDefault() = 0; |
232 | 275 |
233 // Function that sets Chrome as the default web client. Returns false if | 276 // Function that sets Chrome as the default web client. |
234 // the operation fails or has been cancelled by the user. | 277 virtual void SetAsDefault(bool interactive_permitted) = 0; |
235 virtual bool SetAsDefault(bool interactive_permitted) = 0; | 278 |
279 // Executed before calling |ExecuteSetAsDefault|. | |
280 virtual void InitializeSetAsDefault() {} | |
281 | |
282 // Called in CompleteSetAsDefault right. Should return true to notify the | |
283 // observer of the result of setting Chrome as the default browser. | |
284 virtual bool UninitializeSetAsDefault(bool succeeded) { return true; } | |
236 | 285 |
237 // Function that handles performing the check on the file thread. This | 286 // Function that handles performing the check on the file thread. This |
238 // function is posted as a task onto the file thread, where it performs | 287 // function is posted as a task onto the file thread, where it performs |
239 // the check. When the check has finished the CompleteCheckIsDefault | 288 // the check. When the check has finished the CompleteCheckIsDefault |
240 // function is posted to the UI thread, where the result is sent back to | 289 // function is posted to the UI thread, where the result is sent back to |
241 // the observer. | 290 // the observer. |
242 void ExecuteCheckIsDefault(); | 291 void ExecuteCheckIsDefault(); |
243 | 292 |
244 // Function that handles setting Chrome as the default web client on the | 293 // Function that handles setting Chrome as the default web client on the |
245 // file thread. This function is posted as a task onto the file thread. | 294 // file thread. This function is posted as a task onto the file thread. |
246 // Once it is finished the CompleteSetAsDefault function is posted to the | 295 // Once it is finished the CompleteSetAsDefault function is posted to the |
247 // UI thread which will check the status of Chrome as the default, and | 296 // UI thread which will check the status of Chrome as the default, and |
248 // send this to the observer. | 297 // send this to the observer. |
249 // |interactive_permitted| indicates if the routine is allowed to carry on | 298 // |interactive_permitted| indicates if the routine is allowed to carry on |
250 // in context where user interaction is required (CanSetAsDefault* | 299 // in context where user interaction is required (CanSetAsDefault* |
251 // returns SET_DEFAULT_INTERACTIVE). | 300 // returns SET_DEFAULT_INTERACTIVE). |
252 void ExecuteSetAsDefault(bool interactive_permitted); | 301 void ExecuteSetAsDefault(bool interactive_permitted); |
253 | 302 |
254 // Communicate results to the observer. This function is posted as a task | 303 // Calls |UninitializeSetAsDefault| and then communicate results to the |
255 // onto the UI thread by the ExecuteCheckIsDefault function running in the | 304 // observer. |
256 // file thread. | |
257 void CompleteCheckIsDefault(DefaultWebClientState state); | 305 void CompleteCheckIsDefault(DefaultWebClientState state); |
258 | 306 |
259 // When the action to set Chrome as the default has completed this function | |
260 // is run. It is posted as a task back onto the UI thread by the | |
261 // ExecuteSetAsDefault function running in the file thread. This function | |
262 // will the start the check process, which, if an observer is present, | |
263 // reports to it the new status. | |
264 // |succeeded| is true if the actual call to a set-default function (from | |
265 // ExecuteSetAsDefault) was successful. | |
266 void CompleteSetAsDefault(bool succeeded); | |
267 | |
268 // Updates the UI in our associated view with the current default web | 307 // Updates the UI in our associated view with the current default web |
269 // client state. | 308 // client state. |
270 void UpdateUI(DefaultWebClientState state); | 309 void UpdateUI(DefaultWebClientState state); |
271 | 310 |
272 DefaultWebClientObserver* observer_; | 311 DefaultWebClientObserver* observer_; |
273 | 312 |
274 DISALLOW_COPY_AND_ASSIGN(DefaultWebClientWorker); | 313 DISALLOW_COPY_AND_ASSIGN(DefaultWebClientWorker); |
275 }; | 314 }; |
276 | 315 |
277 // Worker for checking and setting the default browser. | 316 // Worker for checking and setting the default browser. |
278 class DefaultBrowserWorker : public DefaultWebClientWorker { | 317 class DefaultBrowserWorker : public DefaultWebClientWorker { |
279 public: | 318 public: |
280 explicit DefaultBrowserWorker(DefaultWebClientObserver* observer); | 319 explicit DefaultBrowserWorker(DefaultWebClientObserver* observer); |
281 | 320 |
282 private: | 321 private: |
283 ~DefaultBrowserWorker() override {} | 322 ~DefaultBrowserWorker() override {} |
284 | 323 |
285 // Check if Chrome is the default browser. | 324 // Check if Chrome is the default browser. |
286 DefaultWebClientState CheckIsDefault() override; | 325 DefaultWebClientState CheckIsDefault() override; |
287 | 326 |
288 // Set Chrome as the default browser. | 327 // Set Chrome as the default browser. |
289 bool SetAsDefault(bool interactive_permitted) override; | 328 void SetAsDefault(bool interactive_permitted) override; |
329 | |
330 // On windows 10+, add the URL filter and starts the timer that determines | |
331 // if the operation was successful or not. | |
332 void InitializeSetAsDefault() override; | |
333 | |
334 // On windows 10+, remove the URL filter and stops the timer. | |
335 bool UninitializeSetAsDefault(bool succeeded) override; | |
290 | 336 |
291 DISALLOW_COPY_AND_ASSIGN(DefaultBrowserWorker); | 337 DISALLOW_COPY_AND_ASSIGN(DefaultBrowserWorker); |
292 }; | 338 }; |
293 | 339 |
294 // Worker for checking and setting the default client application | 340 // Worker for checking and setting the default client application |
295 // for a given protocol. A different worker instance is needed for each | 341 // for a given protocol. A different worker instance is needed for each |
296 // protocol you are interested in, so to check or set the default for | 342 // protocol you are interested in, so to check or set the default for |
297 // multiple protocols you should use multiple worker objects. | 343 // multiple protocols you should use multiple worker objects. |
298 class DefaultProtocolClientWorker : public DefaultWebClientWorker { | 344 class DefaultProtocolClientWorker : public DefaultWebClientWorker { |
299 public: | 345 public: |
300 DefaultProtocolClientWorker(DefaultWebClientObserver* observer, | 346 DefaultProtocolClientWorker(DefaultWebClientObserver* observer, |
301 const std::string& protocol); | 347 const std::string& protocol); |
302 | 348 |
303 const std::string& protocol() const { return protocol_; } | 349 const std::string& protocol() const { return protocol_; } |
304 | 350 |
305 protected: | 351 protected: |
306 ~DefaultProtocolClientWorker() override {} | 352 ~DefaultProtocolClientWorker() override {} |
307 | 353 |
308 private: | 354 private: |
309 // Check is Chrome is the default handler for this protocol. | 355 // Check is Chrome is the default handler for this protocol. |
310 DefaultWebClientState CheckIsDefault() override; | 356 DefaultWebClientState CheckIsDefault() override; |
311 | 357 |
312 // Set Chrome as the default handler for this protocol. | 358 // Set Chrome as the default handler for this protocol. |
313 bool SetAsDefault(bool interactive_permitted) override; | 359 void SetAsDefault(bool interactive_permitted) override; |
314 | 360 |
315 std::string protocol_; | 361 std::string protocol_; |
316 | 362 |
317 DISALLOW_COPY_AND_ASSIGN(DefaultProtocolClientWorker); | 363 DISALLOW_COPY_AND_ASSIGN(DefaultProtocolClientWorker); |
318 }; | 364 }; |
319 }; | 365 }; |
320 | 366 |
321 #endif // CHROME_BROWSER_SHELL_INTEGRATION_H_ | 367 #endif // CHROME_BROWSER_SHELL_INTEGRATION_H_ |
OLD | NEW |