| 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/time/time.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; |
| 20 class OneShotTimer; |
| 19 } | 21 } |
| 20 | 22 |
| 21 class ShellIntegration { | 23 class ShellIntegration { |
| 22 public: | 24 public: |
| 23 // Sets Chrome as the default browser (only for the current user). Returns | 25 // Sets Chrome as the default browser (only for the current user). Returns |
| 24 // false if this operation fails. | 26 // false if this operation fails. |
| 25 static bool SetAsDefaultBrowser(); | 27 static bool SetAsDefaultBrowser(); |
| 26 | 28 |
| 27 // Initiates an OS shell flow which (if followed by the user) should set | 29 // 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 | 30 // 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 | 31 // 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 | 32 // 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 | 33 // thread. If Chrome is already default browser, no interactive dialog will be |
| 32 // shown and this method returns true. | 34 // shown and this method returns true. |
| 33 static bool SetAsDefaultBrowserInteractive(); | 35 static bool SetAsDefaultBrowserInteractive(); |
| 34 | 36 |
| 37 // Returns true if setting the default browser is an asynchronous operation. |
| 38 // In practice, this is only true on Windows 10+. |
| 39 static bool IsSetAsDefaultAsynchronous(); |
| 40 |
| 35 // Sets Chrome as the default client application for the given protocol | 41 // Sets Chrome as the default client application for the given protocol |
| 36 // (only for the current user). Returns false if this operation fails. | 42 // (only for the current user). Returns false if this operation fails. |
| 37 static bool SetAsDefaultProtocolClient(const std::string& protocol); | 43 static bool SetAsDefaultProtocolClient(const std::string& protocol); |
| 38 | 44 |
| 39 // Initiates an OS shell flow which (if followed by the user) should set | 45 // 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 | 46 // 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) | 47 // 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 | 48 // 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 | 49 // a FILE thread. If Chrome is already default for |protocol|, no interactive |
| 44 // dialog will be shown and this method returns true. | 50 // dialog will be shown and this method returns true. |
| 45 static bool SetAsDefaultProtocolClientInteractive( | 51 static bool SetAsDefaultProtocolClientInteractive( |
| 46 const std::string& protocol); | 52 const std::string& protocol); |
| 47 | 53 |
| 48 // In Windows 8 a browser can be made default-in-metro only in an interactive | 54 // Windows 8 and Windows 10 introduced different ways to set the default |
| 49 // flow. We will distinguish between two types of permissions here to avoid | 55 // browser. |
| 50 // forcing the user into UI interaction when this should not be done. | |
| 51 enum DefaultWebClientSetPermission { | 56 enum DefaultWebClientSetPermission { |
| 57 // The browser distribution is not permitted to be made default. |
| 52 SET_DEFAULT_NOT_ALLOWED, | 58 SET_DEFAULT_NOT_ALLOWED, |
| 59 // No special permission or interaction is required to set the default |
| 60 // browser. This is used in Linux, Mac and Windows 7 and under. |
| 53 SET_DEFAULT_UNATTENDED, | 61 SET_DEFAULT_UNATTENDED, |
| 62 // On Windows 8, a browser can be made default only in an interactive flow. |
| 54 SET_DEFAULT_INTERACTIVE, | 63 SET_DEFAULT_INTERACTIVE, |
| 64 // On Windows 10+, the set default browser flow is both interactive and |
| 65 // asynchronous. |
| 66 SET_DEFAULT_ASYNCHRONOUS, |
| 55 }; | 67 }; |
| 56 | 68 |
| 57 // Returns requirements for making the running browser the user's default. | 69 // Returns requirements for making the running browser the user's default. |
| 58 static DefaultWebClientSetPermission CanSetAsDefaultBrowser(); | 70 static DefaultWebClientSetPermission CanSetAsDefaultBrowser(); |
| 59 | 71 |
| 60 // Returns requirements for making the running browser the user's default | 72 // Returns requirements for making the running browser the user's default |
| 61 // client application for specific protocols. | 73 // client application for specific protocols. |
| 62 static DefaultWebClientSetPermission CanSetAsDefaultProtocolClient(); | 74 static DefaultWebClientSetPermission CanSetAsDefaultProtocolClient(); |
| 63 | 75 |
| 64 // Returns true if making the running browser the default client for any | 76 // Returns true if making the running browser the default client for any |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 // observer, once the operation has completed the new default will be | 229 // observer, once the operation has completed the new default will be |
| 218 // queried and the current status reported via SetDefaultWebClientUIState. | 230 // queried and the current status reported via SetDefaultWebClientUIState. |
| 219 void StartSetAsDefault(); | 231 void StartSetAsDefault(); |
| 220 | 232 |
| 221 // Called to notify the worker that the view is gone. | 233 // Called to notify the worker that the view is gone. |
| 222 void ObserverDestroyed(); | 234 void ObserverDestroyed(); |
| 223 | 235 |
| 224 protected: | 236 protected: |
| 225 friend class base::RefCountedThreadSafe<DefaultWebClientWorker>; | 237 friend class base::RefCountedThreadSafe<DefaultWebClientWorker>; |
| 226 | 238 |
| 227 virtual ~DefaultWebClientWorker() {} | 239 // Possible result codes for a set-as-default operation. |
| 240 // Do not modify the ordering as it is important for UMA. |
| 241 enum AttemptResult { |
| 242 // No errors encountered. |
| 243 SUCCESS, |
| 244 // Chrome was already the default web client. This counts as a successful |
| 245 // attempt. |
| 246 ALREADY_DEFAULT, |
| 247 // Chrome was not set as the default web client. |
| 248 FAILURE, |
| 249 // The attempt was abandoned because the observer was destroyed. |
| 250 ABANDONED, |
| 251 // Failed to launch the process to set Chrome as the default web client |
| 252 // asynchronously. |
| 253 LAUNCH_FAILURE, |
| 254 // Another worker is already in progress to make Chrome the default web |
| 255 // client. |
| 256 OTHER_WORKER, |
| 257 // The user initiated another attempt while the asynchronous operation was |
| 258 // already in progress. |
| 259 RETRY, |
| 260 NUM_ATTEMPT_RESULT_TYPES |
| 261 }; |
| 262 |
| 263 virtual ~DefaultWebClientWorker(); |
| 264 |
| 265 // Communicates the result to the observer. In contrast to |
| 266 // OnSetAsDefaultAttemptComplete(), this should not be called multiple |
| 267 // times. |
| 268 void OnCheckIsDefaultComplete(DefaultWebClientState state); |
| 269 |
| 270 // Called when the set as default operation is completed. This then invokes |
| 271 // FinalizeSetAsDefault() and, if an observer is present, starts the check |
| 272 // is default process. |
| 273 // It is safe to call this multiple times. Only the first call is processed |
| 274 // after StartSetAsDefault() is invoked. |
| 275 void OnSetAsDefaultAttemptComplete(AttemptResult result); |
| 276 |
| 277 // Returns true if FinalizeSetAsDefault() will be called. |
| 278 bool set_as_default_initialized() const { |
| 279 return set_as_default_initialized_; |
| 280 } |
| 281 |
| 282 // Flag that indicates if the set-as-default operation is in progess to |
| 283 // prevent multiple notifications to the observer. |
| 284 bool set_as_default_in_progress_ = false; |
| 228 | 285 |
| 229 private: | 286 private: |
| 230 // Function that performs the check. | 287 // Checks whether Chrome is the default web client. Always called on the |
| 231 virtual DefaultWebClientState CheckIsDefault() = 0; | 288 // FILE thread. Subclasses are responsible for calling |
| 289 // OnCheckIsDefaultComplete() on the UI thread. |
| 290 virtual void CheckIsDefault() = 0; |
| 232 | 291 |
| 233 // Function that sets Chrome as the default web client. Returns false if | 292 // Sets Chrome as the default web client. Always called on the FILE thread. |
| 234 // the operation fails or has been cancelled by the user. | 293 // |interactive_permitted| will make SetAsDefault() fail if it requires |
| 235 virtual bool SetAsDefault(bool interactive_permitted) = 0; | 294 // interaction with the user. Subclasses are responsible for calling |
| 295 // OnSetAsDefaultAttemptComplete() on the UI thread. |
| 296 virtual void SetAsDefault(bool interactive_permitted) = 0; |
| 236 | 297 |
| 237 // Function that handles performing the check on the file thread. This | 298 // Invoked on the UI thread prior to starting a set-as-default operation. |
| 238 // function is posted as a task onto the file thread, where it performs | 299 // Returns true if the initialization succeeded and a subsequent call to |
| 239 // the check. When the check has finished the CompleteCheckIsDefault | 300 // FinalizeSetAsDefault() is required. |
| 240 // function is posted to the UI thread, where the result is sent back to | 301 virtual bool InitializeSetAsDefault(); |
| 241 // the observer. | |
| 242 void ExecuteCheckIsDefault(); | |
| 243 | 302 |
| 244 // Communicate results to the observer. This function is posted as a task | 303 // Invoked on the UI thread following a set-as-default operation. |
| 245 // onto the UI thread by the ExecuteCheckIsDefault function running in the | 304 virtual void FinalizeSetAsDefault(); |
| 246 // file thread. | |
| 247 void CompleteCheckIsDefault(DefaultWebClientState state); | |
| 248 | 305 |
| 249 // Function that handles setting Chrome as the default web client on the | 306 // Returns true if the attempt results should be reported to UMA. |
| 250 // file thread. This function is posted as a task onto the file thread. | 307 static bool ShouldReportAttemptResults(); |
| 251 // Once it is finished the CompleteSetAsDefault function is posted to the | |
| 252 // UI thread which will check the status of Chrome as the default, and | |
| 253 // send this to the observer. | |
| 254 // |interactive_permitted| indicates if the routine is allowed to carry on | |
| 255 // in context where user interaction is required (CanSetAsDefault* | |
| 256 // returns SET_DEFAULT_INTERACTIVE). | |
| 257 void ExecuteSetAsDefault(bool interactive_permitted); | |
| 258 | 308 |
| 259 // When the action to set Chrome as the default has completed this function | 309 // Reports the result and duration for one set-as-default attempt. |
| 260 // is run. It is posted as a task back onto the UI thread by the | 310 void ReportAttemptResult(AttemptResult result); |
| 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 | 311 |
| 268 // Updates the UI in our associated view with the current default web | 312 // Updates the UI in our associated view with the current default web |
| 269 // client state. | 313 // client state. |
| 270 void UpdateUI(DefaultWebClientState state); | 314 void UpdateUI(DefaultWebClientState state); |
| 271 | 315 |
| 272 DefaultWebClientObserver* observer_; | 316 DefaultWebClientObserver* observer_; |
| 273 | 317 |
| 318 // Flag that indicates the return value of InitializeSetAsDefault(). If |
| 319 // true, FinalizeSetAsDefault() will be called to clear what was |
| 320 // initialized. |
| 321 bool set_as_default_initialized_ = false; |
| 322 |
| 323 // Records the time it takes to set the default browser. |
| 324 base::TimeTicks start_time_; |
| 325 |
| 274 DISALLOW_COPY_AND_ASSIGN(DefaultWebClientWorker); | 326 DISALLOW_COPY_AND_ASSIGN(DefaultWebClientWorker); |
| 275 }; | 327 }; |
| 276 | 328 |
| 277 // Worker for checking and setting the default browser. | 329 // Worker for checking and setting the default browser. |
| 278 class DefaultBrowserWorker : public DefaultWebClientWorker { | 330 class DefaultBrowserWorker : public DefaultWebClientWorker { |
| 279 public: | 331 public: |
| 280 explicit DefaultBrowserWorker(DefaultWebClientObserver* observer); | 332 explicit DefaultBrowserWorker(DefaultWebClientObserver* observer); |
| 281 | 333 |
| 282 private: | 334 private: |
| 283 ~DefaultBrowserWorker() override {} | 335 ~DefaultBrowserWorker() override; |
| 284 | 336 |
| 285 // Check if Chrome is the default browser. | 337 // Check if Chrome is the default browser. |
| 286 DefaultWebClientState CheckIsDefault() override; | 338 void CheckIsDefault() override; |
| 287 | 339 |
| 288 // Set Chrome as the default browser. | 340 // Set Chrome as the default browser. |
| 289 bool SetAsDefault(bool interactive_permitted) override; | 341 void SetAsDefault(bool interactive_permitted) override; |
| 342 |
| 343 #if defined(OS_WIN) |
| 344 // On Windows 10+, adds the default browser callback and starts the timer |
| 345 // that determines if the operation was successful or not. |
| 346 bool InitializeSetAsDefault() override; |
| 347 |
| 348 // On Windows 10+, removes the default browser callback and stops the timer. |
| 349 void FinalizeSetAsDefault() override; |
| 350 |
| 351 // Prompts the user to select the default browser by trying to open the help |
| 352 // page that explains how to set Chrome as the default browser. Returns |
| 353 // false if the process needed to set Chrome default failed to launch. |
| 354 static bool SetAsDefaultBrowserAsynchronous(); |
| 355 |
| 356 // Used to determine if setting the default browser was unsuccesful. |
| 357 scoped_ptr<base::OneShotTimer> async_timer_; |
| 358 #endif // !defined(OS_WIN) |
| 290 | 359 |
| 291 DISALLOW_COPY_AND_ASSIGN(DefaultBrowserWorker); | 360 DISALLOW_COPY_AND_ASSIGN(DefaultBrowserWorker); |
| 292 }; | 361 }; |
| 293 | 362 |
| 294 // Worker for checking and setting the default client application | 363 // Worker for checking and setting the default client application |
| 295 // for a given protocol. A different worker instance is needed for each | 364 // 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 | 365 // protocol you are interested in, so to check or set the default for |
| 297 // multiple protocols you should use multiple worker objects. | 366 // multiple protocols you should use multiple worker objects. |
| 298 class DefaultProtocolClientWorker : public DefaultWebClientWorker { | 367 class DefaultProtocolClientWorker : public DefaultWebClientWorker { |
| 299 public: | 368 public: |
| 300 DefaultProtocolClientWorker(DefaultWebClientObserver* observer, | 369 DefaultProtocolClientWorker(DefaultWebClientObserver* observer, |
| 301 const std::string& protocol); | 370 const std::string& protocol); |
| 302 | 371 |
| 303 const std::string& protocol() const { return protocol_; } | 372 const std::string& protocol() const { return protocol_; } |
| 304 | 373 |
| 305 protected: | 374 protected: |
| 306 ~DefaultProtocolClientWorker() override {} | 375 ~DefaultProtocolClientWorker() override; |
| 307 | 376 |
| 308 private: | 377 private: |
| 309 // Check is Chrome is the default handler for this protocol. | 378 // Check is Chrome is the default handler for this protocol. |
| 310 DefaultWebClientState CheckIsDefault() override; | 379 void CheckIsDefault() override; |
| 311 | 380 |
| 312 // Set Chrome as the default handler for this protocol. | 381 // Set Chrome as the default handler for this protocol. |
| 313 bool SetAsDefault(bool interactive_permitted) override; | 382 void SetAsDefault(bool interactive_permitted) override; |
| 314 | 383 |
| 315 std::string protocol_; | 384 std::string protocol_; |
| 316 | 385 |
| 317 DISALLOW_COPY_AND_ASSIGN(DefaultProtocolClientWorker); | 386 DISALLOW_COPY_AND_ASSIGN(DefaultProtocolClientWorker); |
| 318 }; | 387 }; |
| 319 }; | 388 }; |
| 320 | 389 |
| 321 #endif // CHROME_BROWSER_SHELL_INTEGRATION_H_ | 390 #endif // CHROME_BROWSER_SHELL_INTEGRATION_H_ |
| OLD | NEW |