| 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 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 // Weak ptrs are used to bind this class to the callbacks of the timer and the | 442 // Weak ptrs are used to bind this class to the callbacks of the timer and the |
| 441 // registry watcher. This makes it possible to self-delete after one of the | 443 // registry watcher. This makes it possible to self-delete after one of the |
| 442 // callbacks is executed to cancel the remaining ones. | 444 // callbacks is executed to cancel the remaining ones. |
| 443 base::WeakPtrFactory<OpenSystemSettingsHelper> weak_ptr_factory_; | 445 base::WeakPtrFactory<OpenSystemSettingsHelper> weak_ptr_factory_; |
| 444 | 446 |
| 445 DISALLOW_COPY_AND_ASSIGN(OpenSystemSettingsHelper); | 447 DISALLOW_COPY_AND_ASSIGN(OpenSystemSettingsHelper); |
| 446 }; | 448 }; |
| 447 | 449 |
| 448 OpenSystemSettingsHelper* OpenSystemSettingsHelper::instance_ = nullptr; | 450 OpenSystemSettingsHelper* OpenSystemSettingsHelper::instance_ = nullptr; |
| 449 | 451 |
| 450 void RecordPinnedToTaskbarProcessError(bool error) { | 452 // Helper class to determine if Chrome is pinned to the taskbar. Hides the |
| 451 UMA_HISTOGRAM_BOOLEAN("Windows.IsPinnedToTaskbar.ProcessError", error); | 453 // complexity of managing the lifetime of a UtilityProcessMojoClient. |
| 454 class IsPinnedToTaskbarHelper { |
| 455 public: |
| 456 using ResultCallback = win::IsPinnedToTaskbarCallback; |
| 457 using ErrorCallback = win::ConnectionErrorCallback; |
| 458 static void GetState(const ErrorCallback& error_callback, |
| 459 const ResultCallback& result_callback); |
| 460 |
| 461 private: |
| 462 IsPinnedToTaskbarHelper(const ErrorCallback& error_callback, |
| 463 const ResultCallback& result_callback); |
| 464 |
| 465 void OnConnectionError(); |
| 466 void OnIsPinnedToTaskbarResult(bool succeeded, bool is_pinned_to_taskbar); |
| 467 |
| 468 content::UtilityProcessMojoClient<mojom::ShellHandler> shell_handler_; |
| 469 |
| 470 ErrorCallback error_callback_; |
| 471 ResultCallback result_callback_; |
| 472 |
| 473 DISALLOW_COPY_AND_ASSIGN(IsPinnedToTaskbarHelper); |
| 474 }; |
| 475 |
| 476 // static |
| 477 void IsPinnedToTaskbarHelper::GetState(const ErrorCallback& error_callback, |
| 478 const ResultCallback& result_callback) { |
| 479 // Self-deleting when the ShellHandler completes. |
| 480 new IsPinnedToTaskbarHelper(error_callback, result_callback); |
| 452 } | 481 } |
| 453 | 482 |
| 454 // Record the UMA histogram when a response is received. The callback that binds | 483 IsPinnedToTaskbarHelper::IsPinnedToTaskbarHelper( |
| 455 // to this function holds a reference to the ShellHandlerClient to keep it alive | 484 const ErrorCallback& error_callback, |
| 456 // until invokation. | 485 const ResultCallback& result_callback) |
| 457 void OnIsPinnedToTaskbarResult( | 486 : shell_handler_( |
| 458 content::UtilityProcessMojoClient<mojom::ShellHandler>* client, | 487 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_SHELL_HANDLER_NAME)), |
| 488 error_callback_(error_callback), |
| 489 result_callback_(result_callback) { |
| 490 // |shell_handler_| owns the callbacks and is guaranteed to be destroyed |
| 491 // before |this|, therefore making base::Unretained() safe to use. |
| 492 shell_handler_.set_error_callback(base::Bind( |
| 493 &IsPinnedToTaskbarHelper::OnConnectionError, base::Unretained(this))); |
| 494 shell_handler_.set_disable_sandbox(); |
| 495 shell_handler_.Start(); |
| 496 |
| 497 shell_handler_.service()->IsPinnedToTaskbar( |
| 498 base::Bind(&IsPinnedToTaskbarHelper::OnIsPinnedToTaskbarResult, |
| 499 base::Unretained(this))); |
| 500 } |
| 501 |
| 502 void IsPinnedToTaskbarHelper::OnConnectionError() { |
| 503 error_callback_.Run(); |
| 504 delete this; |
| 505 } |
| 506 |
| 507 void IsPinnedToTaskbarHelper::OnIsPinnedToTaskbarResult( |
| 459 bool succeeded, | 508 bool succeeded, |
| 460 bool is_pinned_to_taskbar) { | 509 bool is_pinned_to_taskbar) { |
| 461 // Clean up the utility process. | 510 result_callback_.Run(succeeded, is_pinned_to_taskbar); |
| 462 delete client; | 511 delete this; |
| 463 | |
| 464 RecordPinnedToTaskbarProcessError(false); | |
| 465 | |
| 466 enum Result { NOT_PINNED, PINNED, FAILURE, NUM_RESULTS }; | |
| 467 | |
| 468 Result result = FAILURE; | |
| 469 if (succeeded) | |
| 470 result = is_pinned_to_taskbar ? PINNED : NOT_PINNED; | |
| 471 UMA_HISTOGRAM_ENUMERATION("Windows.IsPinnedToTaskbar", result, NUM_RESULTS); | |
| 472 } | |
| 473 | |
| 474 // Called when a connection error happen with the shell handler process. A call | |
| 475 // to this function is mutially exclusive with a call to | |
| 476 // OnIsPinnedToTaskbarResult(). | |
| 477 void OnShellHandlerConnectionError( | |
| 478 content::UtilityProcessMojoClient<mojom::ShellHandler>* client) { | |
| 479 // Clean up the utility process. | |
| 480 delete client; | |
| 481 | |
| 482 RecordPinnedToTaskbarProcessError(true); | |
| 483 } | 512 } |
| 484 | 513 |
| 485 } // namespace | 514 } // namespace |
| 486 | 515 |
| 487 bool SetAsDefaultBrowser() { | 516 bool SetAsDefaultBrowser() { |
| 488 base::FilePath chrome_exe; | 517 base::FilePath chrome_exe; |
| 489 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 518 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |
| 490 LOG(ERROR) << "Error getting app exe path"; | 519 LOG(ERROR) << "Error getting app exe path"; |
| 491 return false; | 520 return false; |
| 492 } | 521 } |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 // This needs to happen eventually (e.g. so that the appid is fixed and the | 746 // This needs to happen eventually (e.g. so that the appid is fixed and the |
| 718 // run-time Chrome icon is merged with the taskbar shortcut), but this is not | 747 // run-time Chrome icon is merged with the taskbar shortcut), but this is not |
| 719 // urgent and shouldn't delay Chrome startup. | 748 // urgent and shouldn't delay Chrome startup. |
| 720 static const int64_t kMigrateTaskbarPinsDelaySeconds = 15; | 749 static const int64_t kMigrateTaskbarPinsDelaySeconds = 15; |
| 721 BrowserThread::PostDelayedTask( | 750 BrowserThread::PostDelayedTask( |
| 722 BrowserThread::FILE, FROM_HERE, | 751 BrowserThread::FILE, FROM_HERE, |
| 723 base::Bind(&MigrateTaskbarPinsCallback), | 752 base::Bind(&MigrateTaskbarPinsCallback), |
| 724 base::TimeDelta::FromSeconds(kMigrateTaskbarPinsDelaySeconds)); | 753 base::TimeDelta::FromSeconds(kMigrateTaskbarPinsDelaySeconds)); |
| 725 } | 754 } |
| 726 | 755 |
| 727 void RecordIsPinnedToTaskbarHistogram() { | 756 void GetIsPinnedToTaskbarState( |
| 728 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 757 const ConnectionErrorCallback& on_error_callback, |
| 729 | 758 const IsPinnedToTaskbarCallback& result_callback) { |
| 730 // The code to check if Chrome is pinned to the taskbar brings in shell | 759 IsPinnedToTaskbarHelper::GetState(on_error_callback, result_callback); |
| 731 // extensions which can hinder stability so it is executed in a utility | |
| 732 // process. | |
| 733 content::UtilityProcessMojoClient<mojom::ShellHandler>* client = | |
| 734 new content::UtilityProcessMojoClient<mojom::ShellHandler>( | |
| 735 l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_SHELL_HANDLER_NAME)); | |
| 736 | |
| 737 client->set_error_callback( | |
| 738 base::Bind(&OnShellHandlerConnectionError, client)); | |
| 739 client->set_disable_sandbox(); | |
| 740 client->Start(); | |
| 741 | |
| 742 client->service()->IsPinnedToTaskbar( | |
| 743 base::Bind(&OnIsPinnedToTaskbarResult, client)); | |
| 744 } | 760 } |
| 745 | 761 |
| 746 int MigrateShortcutsInPathInternal(const base::FilePath& chrome_exe, | 762 int MigrateShortcutsInPathInternal(const base::FilePath& chrome_exe, |
| 747 const base::FilePath& path) { | 763 const base::FilePath& path) { |
| 748 DCHECK(base::win::GetVersion() >= base::win::VERSION_WIN7); | 764 DCHECK(base::win::GetVersion() >= base::win::VERSION_WIN7); |
| 749 | 765 |
| 750 // Enumerate all pinned shortcuts in the given path directly. | 766 // Enumerate all pinned shortcuts in the given path directly. |
| 751 base::FileEnumerator shortcuts_enum( | 767 base::FileEnumerator shortcuts_enum( |
| 752 path, false, // not recursive | 768 path, false, // not recursive |
| 753 base::FileEnumerator::FILES, FILE_PATH_LITERAL("*.lnk")); | 769 base::FileEnumerator::FILES, FILE_PATH_LITERAL("*.lnk")); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 if (base::PathExists(shortcut)) | 891 if (base::PathExists(shortcut)) |
| 876 return shortcut; | 892 return shortcut; |
| 877 } | 893 } |
| 878 | 894 |
| 879 return base::FilePath(); | 895 return base::FilePath(); |
| 880 } | 896 } |
| 881 | 897 |
| 882 } // namespace win | 898 } // namespace win |
| 883 | 899 |
| 884 } // namespace shell_integration | 900 } // namespace shell_integration |
| OLD | NEW |