Chromium Code Reviews| 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 #include "chrome/browser/shell_integration_win.h" | 5 #include "chrome/browser/shell_integration_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <shlwapi.h> | 8 #include <shlwapi.h> |
| 9 #include <shobjidl.h> | 9 #include <shobjidl.h> |
| 10 #include <propkey.h> // Needs to come after shobjidl.h. | 10 #include <propkey.h> // Needs to come after shobjidl.h. |
| 11 #include <stddef.h> | 11 #include <stddef.h> |
| 12 #include <stdint.h> | 12 #include <stdint.h> |
| 13 | 13 |
| 14 #include <memory> | |
| 15 #include <utility> | |
| 14 #include <vector> | 16 #include <vector> |
| 15 | 17 |
| 16 #include "base/bind.h" | 18 #include "base/bind.h" |
| 17 #include "base/callback.h" | 19 #include "base/callback.h" |
| 18 #include "base/command_line.h" | 20 #include "base/command_line.h" |
| 19 #include "base/files/file_enumerator.h" | 21 #include "base/files/file_enumerator.h" |
| 20 #include "base/files/file_util.h" | 22 #include "base/files/file_util.h" |
| 21 #include "base/macros.h" | 23 #include "base/macros.h" |
| 22 #include "base/memory/ptr_util.h" | 24 #include "base/memory/ptr_util.h" |
| 23 #include "base/memory/weak_ptr.h" | 25 #include "base/memory/weak_ptr.h" |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 // Weak ptrs are used to bind this class to the callbacks of the timer and the | 427 // Weak ptrs are used to bind this class to the callbacks of the timer and the |
| 426 // registry watcher. This makes it possible to self-delete after one of the | 428 // registry watcher. This makes it possible to self-delete after one of the |
| 427 // callbacks is executed to cancel the remaining ones. | 429 // callbacks is executed to cancel the remaining ones. |
| 428 base::WeakPtrFactory<OpenSystemSettingsHelper> weak_ptr_factory_; | 430 base::WeakPtrFactory<OpenSystemSettingsHelper> weak_ptr_factory_; |
| 429 | 431 |
| 430 DISALLOW_COPY_AND_ASSIGN(OpenSystemSettingsHelper); | 432 DISALLOW_COPY_AND_ASSIGN(OpenSystemSettingsHelper); |
| 431 }; | 433 }; |
| 432 | 434 |
| 433 OpenSystemSettingsHelper* OpenSystemSettingsHelper::instance_ = nullptr; | 435 OpenSystemSettingsHelper* OpenSystemSettingsHelper::instance_ = nullptr; |
| 434 | 436 |
| 435 void RecordPinnedToTaskbarProcessError(bool error) { | 437 // Helper class to determine if Chrome is pinned to the taskbar. Hides the |
| 436 UMA_HISTOGRAM_BOOLEAN("Windows.IsPinnedToTaskbar.ProcessError", error); | 438 // complexity of managing the lifetime of |shell_handler_|. |
|
grt (UTC plus 2)
2016/11/22 10:06:41
nit: "...of a UtilityProcessMojoClient."
Patrick Monette
2016/11/22 22:41:59
Done.
| |
| 439 class IsPinnedToTaskbarHelper { | |
| 440 public: | |
| 441 using ResultCallback = win::IsPinnedToTaskbarCallback; | |
| 442 using ErrorCallback = win::ConnectionErrorCallback; | |
| 443 static void GetState(const ErrorCallback& error_callback, | |
| 444 const ResultCallback& result_callback); | |
| 445 | |
| 446 private: | |
| 447 IsPinnedToTaskbarHelper(const ErrorCallback& error_callback, | |
| 448 const ResultCallback& result_callback); | |
| 449 | |
| 450 void OnConnectionError(); | |
| 451 void OnIsPinnedToTaskbarResult(bool succeeded, bool is_pinned_to_taskbar); | |
| 452 | |
| 453 content::UtilityProcessMojoClient<mojom::ShellHandler> shell_handler_; | |
| 454 | |
| 455 ErrorCallback error_callback_; | |
| 456 ResultCallback result_callback_; | |
| 457 | |
| 458 DISALLOW_COPY_AND_ASSIGN(IsPinnedToTaskbarHelper); | |
| 459 }; | |
| 460 | |
| 461 // static | |
| 462 void IsPinnedToTaskbarHelper::GetState(const ErrorCallback& error_callback, | |
| 463 const ResultCallback& result_callback) { | |
| 464 // Self-deleting when the ShellHandler completes. | |
| 465 new IsPinnedToTaskbarHelper(error_callback, result_callback); | |
| 437 } | 466 } |
| 438 | 467 |
| 439 // Record the UMA histogram when a response is received. The callback that binds | 468 IsPinnedToTaskbarHelper::IsPinnedToTaskbarHelper( |
| 440 // to this function holds a reference to the ShellHandlerClient to keep it alive | 469 const ErrorCallback& error_callback, |
| 441 // until invokation. | 470 const ResultCallback& result_callback) |
| 442 void OnIsPinnedToTaskbarResult( | 471 : shell_handler_( |
| 443 content::UtilityProcessMojoClient<mojom::ShellHandler>* client, | 472 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_SHELL_HANDLER_NAME)), |
| 473 error_callback_(error_callback), | |
| 474 result_callback_(result_callback) { | |
| 475 shell_handler_.set_error_callback(base::Bind( | |
| 476 &IsPinnedToTaskbarHelper::OnConnectionError, base::Unretained(this))); | |
| 477 shell_handler_.set_disable_sandbox(); | |
| 478 shell_handler_.Start(); | |
| 479 | |
| 480 shell_handler_.service()->IsPinnedToTaskbar( | |
| 481 base::Bind(&IsPinnedToTaskbarHelper::OnIsPinnedToTaskbarResult, | |
| 482 base::Unretained(this))); | |
| 483 } | |
| 484 | |
| 485 void IsPinnedToTaskbarHelper::OnConnectionError() { | |
| 486 error_callback_.Run(); | |
| 487 delete this; | |
| 488 } | |
| 489 | |
| 490 void IsPinnedToTaskbarHelper::OnIsPinnedToTaskbarResult( | |
| 444 bool succeeded, | 491 bool succeeded, |
| 445 bool is_pinned_to_taskbar) { | 492 bool is_pinned_to_taskbar) { |
| 446 // Clean up the utility process. | 493 result_callback_.Run(succeeded, is_pinned_to_taskbar); |
| 447 delete client; | 494 delete this; |
| 448 | |
| 449 RecordPinnedToTaskbarProcessError(false); | |
| 450 | |
| 451 enum Result { NOT_PINNED, PINNED, FAILURE, NUM_RESULTS }; | |
| 452 | |
| 453 Result result = FAILURE; | |
| 454 if (succeeded) | |
| 455 result = is_pinned_to_taskbar ? PINNED : NOT_PINNED; | |
| 456 UMA_HISTOGRAM_ENUMERATION("Windows.IsPinnedToTaskbar", result, NUM_RESULTS); | |
| 457 } | |
| 458 | |
| 459 // Called when a connection error happen with the shell handler process. A call | |
| 460 // to this function is mutially exclusive with a call to | |
| 461 // OnIsPinnedToTaskbarResult(). | |
| 462 void OnShellHandlerConnectionError( | |
| 463 content::UtilityProcessMojoClient<mojom::ShellHandler>* client) { | |
| 464 // Clean up the utility process. | |
| 465 delete client; | |
| 466 | |
| 467 RecordPinnedToTaskbarProcessError(true); | |
| 468 } | 495 } |
| 469 | 496 |
| 470 } // namespace | 497 } // namespace |
| 471 | 498 |
| 472 bool SetAsDefaultBrowser() { | 499 bool SetAsDefaultBrowser() { |
| 473 base::FilePath chrome_exe; | 500 base::FilePath chrome_exe; |
| 474 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 501 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |
| 475 LOG(ERROR) << "Error getting app exe path"; | 502 LOG(ERROR) << "Error getting app exe path"; |
| 476 return false; | 503 return false; |
| 477 } | 504 } |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 702 // This needs to happen eventually (e.g. so that the appid is fixed and the | 729 // This needs to happen eventually (e.g. so that the appid is fixed and the |
| 703 // run-time Chrome icon is merged with the taskbar shortcut), but this is not | 730 // run-time Chrome icon is merged with the taskbar shortcut), but this is not |
| 704 // urgent and shouldn't delay Chrome startup. | 731 // urgent and shouldn't delay Chrome startup. |
| 705 static const int64_t kMigrateTaskbarPinsDelaySeconds = 15; | 732 static const int64_t kMigrateTaskbarPinsDelaySeconds = 15; |
| 706 BrowserThread::PostDelayedTask( | 733 BrowserThread::PostDelayedTask( |
| 707 BrowserThread::FILE, FROM_HERE, | 734 BrowserThread::FILE, FROM_HERE, |
| 708 base::Bind(&MigrateTaskbarPinsCallback), | 735 base::Bind(&MigrateTaskbarPinsCallback), |
| 709 base::TimeDelta::FromSeconds(kMigrateTaskbarPinsDelaySeconds)); | 736 base::TimeDelta::FromSeconds(kMigrateTaskbarPinsDelaySeconds)); |
| 710 } | 737 } |
| 711 | 738 |
| 712 void RecordIsPinnedToTaskbarHistogram() { | 739 void GetIsPinnedToTaskbarState( |
| 713 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 740 const ConnectionErrorCallback& on_error_callback, |
| 714 | 741 const IsPinnedToTaskbarCallback& result_callback) { |
| 715 // The code to check if Chrome is pinned to the taskbar brings in shell | 742 IsPinnedToTaskbarHelper::GetState(on_error_callback, result_callback); |
| 716 // extensions which can hinder stability so it is executed in a utility | |
| 717 // process. | |
| 718 content::UtilityProcessMojoClient<mojom::ShellHandler>* client = | |
| 719 new content::UtilityProcessMojoClient<mojom::ShellHandler>( | |
| 720 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_SHELL_HANDLER_NAME)); | |
| 721 | |
| 722 client->set_error_callback( | |
| 723 base::Bind(&OnShellHandlerConnectionError, client)); | |
| 724 client->set_disable_sandbox(); | |
| 725 client->Start(); | |
| 726 | |
| 727 client->service()->IsPinnedToTaskbar( | |
| 728 base::Bind(&OnIsPinnedToTaskbarResult, client)); | |
| 729 } | 743 } |
| 730 | 744 |
| 731 int MigrateShortcutsInPathInternal(const base::FilePath& chrome_exe, | 745 int MigrateShortcutsInPathInternal(const base::FilePath& chrome_exe, |
| 732 const base::FilePath& path) { | 746 const base::FilePath& path) { |
| 733 DCHECK(base::win::GetVersion() >= base::win::VERSION_WIN7); | 747 DCHECK(base::win::GetVersion() >= base::win::VERSION_WIN7); |
| 734 | 748 |
| 735 // Enumerate all pinned shortcuts in the given path directly. | 749 // Enumerate all pinned shortcuts in the given path directly. |
| 736 base::FileEnumerator shortcuts_enum( | 750 base::FileEnumerator shortcuts_enum( |
| 737 path, false, // not recursive | 751 path, false, // not recursive |
| 738 base::FileEnumerator::FILES, FILE_PATH_LITERAL("*.lnk")); | 752 base::FileEnumerator::FILES, FILE_PATH_LITERAL("*.lnk")); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 860 if (base::PathExists(shortcut)) | 874 if (base::PathExists(shortcut)) |
| 861 return shortcut; | 875 return shortcut; |
| 862 } | 876 } |
| 863 | 877 |
| 864 return base::FilePath(); | 878 return base::FilePath(); |
| 865 } | 879 } |
| 866 | 880 |
| 867 } // namespace win | 881 } // namespace win |
| 868 | 882 |
| 869 } // namespace shell_integration | 883 } // namespace shell_integration |
| OLD | NEW |