| 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 <vector> | 14 #include <vector> | 
| 15 | 15 | 
| 16 #include "base/bind.h" | 16 #include "base/bind.h" | 
| 17 #include "base/callback.h" | 17 #include "base/callback.h" | 
| 18 #include "base/command_line.h" | 18 #include "base/command_line.h" | 
| 19 #include "base/files/file_enumerator.h" | 19 #include "base/files/file_enumerator.h" | 
| 20 #include "base/files/file_util.h" | 20 #include "base/files/file_util.h" | 
| 21 #include "base/macros.h" | 21 #include "base/macros.h" | 
| 22 #include "base/memory/ptr_util.h" | 22 #include "base/memory/ptr_util.h" | 
| 23 #include "base/memory/weak_ptr.h" | 23 #include "base/memory/weak_ptr.h" | 
| 24 #include "base/message_loop/message_loop.h" | 24 #include "base/message_loop/message_loop.h" | 
| 25 #include "base/metrics/histogram_macros.h" | 25 #include "base/metrics/histogram_macros.h" | 
|  | 26 #include "base/metrics/user_metrics.h" | 
|  | 27 #include "base/metrics/user_metrics_action.h" | 
| 26 #include "base/path_service.h" | 28 #include "base/path_service.h" | 
| 27 #include "base/strings/string_util.h" | 29 #include "base/strings/string_util.h" | 
| 28 #include "base/strings/stringprintf.h" | 30 #include "base/strings/stringprintf.h" | 
| 29 #include "base/strings/utf_string_conversions.h" | 31 #include "base/strings/utf_string_conversions.h" | 
| 30 #include "base/time/time.h" | 32 #include "base/time/time.h" | 
| 31 #include "base/timer/timer.h" | 33 #include "base/timer/timer.h" | 
| 32 #include "base/win/registry.h" | 34 #include "base/win/registry.h" | 
| 33 #include "base/win/scoped_comptr.h" | 35 #include "base/win/scoped_comptr.h" | 
| 34 #include "base/win/scoped_propvariant.h" | 36 #include "base/win/scoped_propvariant.h" | 
| 35 #include "base/win/shortcut.h" | 37 #include "base/win/shortcut.h" | 
| 36 #include "base/win/windows_version.h" | 38 #include "base/win/windows_version.h" | 
| 37 #include "chrome/browser/policy/policy_path_parser.h" | 39 #include "chrome/browser/policy/policy_path_parser.h" | 
|  | 40 #include "chrome/browser/settings_app_monitor_win.h" | 
| 38 #include "chrome/browser/shell_integration.h" | 41 #include "chrome/browser/shell_integration.h" | 
| 39 #include "chrome/browser/web_applications/web_app.h" | 42 #include "chrome/browser/web_applications/web_app.h" | 
| 40 #include "chrome/common/chrome_constants.h" | 43 #include "chrome/common/chrome_constants.h" | 
| 41 #include "chrome/common/chrome_paths_internal.h" | 44 #include "chrome/common/chrome_paths_internal.h" | 
| 42 #include "chrome/common/chrome_switches.h" | 45 #include "chrome/common/chrome_switches.h" | 
| 43 #include "chrome/installer/setup/setup_util.h" | 46 #include "chrome/installer/setup/setup_util.h" | 
| 44 #include "chrome/installer/util/browser_distribution.h" | 47 #include "chrome/installer/util/browser_distribution.h" | 
| 45 #include "chrome/installer/util/create_reg_key_work_item.h" | 48 #include "chrome/installer/util/create_reg_key_work_item.h" | 
| 46 #include "chrome/installer/util/install_util.h" | 49 #include "chrome/installer/util/install_util.h" | 
| 47 #include "chrome/installer/util/scoped_user_protocol_entry.h" | 50 #include "chrome/installer/util/scoped_user_protocol_entry.h" | 
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 207     case ShellUtil::NOT_DEFAULT: | 210     case ShellUtil::NOT_DEFAULT: | 
| 208       return DefaultWebClientState::NOT_DEFAULT; | 211       return DefaultWebClientState::NOT_DEFAULT; | 
| 209     case ShellUtil::IS_DEFAULT: | 212     case ShellUtil::IS_DEFAULT: | 
| 210       return DefaultWebClientState::IS_DEFAULT; | 213       return DefaultWebClientState::IS_DEFAULT; | 
| 211     default: | 214     default: | 
| 212       DCHECK_EQ(ShellUtil::UNKNOWN_DEFAULT, default_state); | 215       DCHECK_EQ(ShellUtil::UNKNOWN_DEFAULT, default_state); | 
| 213       return DefaultWebClientState::UNKNOWN_DEFAULT; | 216       return DefaultWebClientState::UNKNOWN_DEFAULT; | 
| 214   } | 217   } | 
| 215 } | 218 } | 
| 216 | 219 | 
|  | 220 // A recorder of user actions in the Windows Settings app. | 
|  | 221 class DefaultBrowserActionRecorder : public win::SettingsAppMonitor::Delegate { | 
|  | 222  public: | 
|  | 223   // Creates the recorder and the monitor that drives it. |continuation| will be | 
|  | 224   // run once the monitor's initialization completes (regardless of success or | 
|  | 225   // failure). | 
|  | 226   explicit DefaultBrowserActionRecorder(base::Closure continuation) | 
|  | 227       : continuation_(std::move(continuation)), settings_app_monitor_(this) {} | 
|  | 228 | 
|  | 229  private: | 
|  | 230   // win::SettingsAppMonitor::Delegate: | 
|  | 231   void OnInitialized(HRESULT result) override { | 
|  | 232     if (SUCCEEDED(result)) { | 
|  | 233       base::RecordAction( | 
|  | 234           base::UserMetricsAction("SettingsAppMonitor.Initialized")); | 
|  | 235     } else { | 
|  | 236       base::RecordAction(base::UserMetricsAction("SettingsAppMonitor.Failed")); | 
|  | 237     } | 
|  | 238     continuation_.Run(); | 
|  | 239     continuation_ = base::Closure(); | 
|  | 240   } | 
|  | 241 | 
|  | 242   void OnAppFocused() override { | 
|  | 243     base::RecordAction( | 
|  | 244         base::UserMetricsAction("SettingsAppMonitor.AppFocused")); | 
|  | 245   } | 
|  | 246 | 
|  | 247   void OnChooserInvoked() override { | 
|  | 248     base::RecordAction( | 
|  | 249         base::UserMetricsAction("SettingsAppMonitor.ChooserInvoked")); | 
|  | 250   } | 
|  | 251 | 
|  | 252   void OnBrowserChosen(const base::string16& browser_name) override { | 
|  | 253     if (browser_name == | 
|  | 254         BrowserDistribution::GetDistribution()->GetDisplayName()) { | 
|  | 255       base::RecordAction( | 
|  | 256           base::UserMetricsAction("SettingsAppMonitor.ChromeBrowserChosen")); | 
|  | 257     } else { | 
|  | 258       base::RecordAction( | 
|  | 259           base::UserMetricsAction("SettingsAppMonitor.OtherBrowserChosen")); | 
|  | 260     } | 
|  | 261   } | 
|  | 262 | 
|  | 263   // A closure to be run once initialization completes. | 
|  | 264   base::Closure continuation_; | 
|  | 265 | 
|  | 266   // Monitors user interaction with the Windows Settings app for the sake of | 
|  | 267   // reporting user actions. | 
|  | 268   win::SettingsAppMonitor settings_app_monitor_; | 
|  | 269 | 
|  | 270   DISALLOW_COPY_AND_ASSIGN(DefaultBrowserActionRecorder); | 
|  | 271 }; | 
|  | 272 | 
|  | 273 // A function bound up in a callback with a DefaultBrowserActionRecorder and | 
|  | 274 // a closure to keep the former alive until the time comes to run the latter. | 
|  | 275 void OnSettingsAppFinished( | 
|  | 276     std::unique_ptr<DefaultBrowserActionRecorder> recorder, | 
|  | 277     const base::Closure& on_finished_callback) { | 
|  | 278   recorder.reset(); | 
|  | 279   on_finished_callback.Run(); | 
|  | 280 } | 
|  | 281 | 
| 217 // There is no way to make sure the user is done with the system settings, but a | 282 // There is no way to make sure the user is done with the system settings, but a | 
| 218 // signal that the interaction is finished is needed for UMA. A timer of 2 | 283 // signal that the interaction is finished is needed for UMA. A timer of 2 | 
| 219 // minutes is used as a substitute. The registry keys for the protocol | 284 // minutes is used as a substitute. The registry keys for the protocol | 
| 220 // association with an app are also monitored to signal the end of the | 285 // association with an app are also monitored to signal the end of the | 
| 221 // interaction early when it is clear that the user made a choice (e.g. http | 286 // interaction early when it is clear that the user made a choice (e.g. http | 
| 222 // and https for default browser). | 287 // and https for default browser). | 
| 223 // | 288 // | 
| 224 // This helper class manages both the timer and the registry watchers and makes | 289 // This helper class manages both the timer and the registry watchers and makes | 
| 225 // sure the callback for the end of the settings interaction is only run once. | 290 // sure the callback for the end of the settings interaction is only run once. | 
| 226 // This class also manages its own lifetime. | 291 // This class also manages its own lifetime. | 
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 472     const base::Closure& on_finished_callback) { | 537     const base::Closure& on_finished_callback) { | 
| 473   DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 538   DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 
| 474 | 539 | 
| 475   base::FilePath chrome_exe; | 540   base::FilePath chrome_exe; | 
| 476   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 541   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 
| 477     NOTREACHED() << "Error getting app exe path"; | 542     NOTREACHED() << "Error getting app exe path"; | 
| 478     on_finished_callback.Run(); | 543     on_finished_callback.Run(); | 
| 479     return; | 544     return; | 
| 480   } | 545   } | 
| 481 | 546 | 
| 482   // The helper manages its own lifetime. | 547   // Create an action recorder that will open the settings app once it has | 
|  | 548   // initialized. | 
|  | 549   std::unique_ptr<DefaultBrowserActionRecorder> recorder( | 
|  | 550       new DefaultBrowserActionRecorder(base::Bind( | 
|  | 551           base::IgnoreResult(&ShellUtil::ShowMakeChromeDefaultSystemUI), | 
|  | 552           base::Unretained(BrowserDistribution::GetDistribution()), | 
|  | 553           chrome_exe))); | 
|  | 554 | 
|  | 555   // The helper manages its own lifetime. Bind the action recorder | 
|  | 556   // into the finished callback to keep it alive throughout the | 
|  | 557   // interaction. | 
| 483   static const wchar_t* const kProtocols[] = {L"http", L"https", nullptr}; | 558   static const wchar_t* const kProtocols[] = {L"http", L"https", nullptr}; | 
| 484   OpenSystemSettingsHelper::Begin(kProtocols, on_finished_callback); | 559   OpenSystemSettingsHelper::Begin( | 
| 485 | 560       kProtocols, base::Bind(&OnSettingsAppFinished, base::Passed(&recorder), | 
| 486   BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 561                              on_finished_callback)); | 
| 487   ShellUtil::ShowMakeChromeDefaultSystemUI(dist, chrome_exe); |  | 
| 488 } | 562 } | 
| 489 | 563 | 
| 490 bool SetAsDefaultProtocolClientUsingIntentPicker(const std::string& protocol) { | 564 bool SetAsDefaultProtocolClientUsingIntentPicker(const std::string& protocol) { | 
| 491   base::FilePath chrome_exe; | 565   base::FilePath chrome_exe; | 
| 492   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 566   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 
| 493     NOTREACHED() << "Error getting app exe path"; | 567     NOTREACHED() << "Error getting app exe path"; | 
| 494     return false; | 568     return false; | 
| 495   } | 569   } | 
| 496 | 570 | 
| 497   BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 571   BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 698     if (base::PathExists(shortcut)) | 772     if (base::PathExists(shortcut)) | 
| 699       return shortcut; | 773       return shortcut; | 
| 700   } | 774   } | 
| 701 | 775 | 
| 702   return base::FilePath(); | 776   return base::FilePath(); | 
| 703 } | 777 } | 
| 704 | 778 | 
| 705 }  // namespace win | 779 }  // namespace win | 
| 706 | 780 | 
| 707 }  // namespace shell_integration | 781 }  // namespace shell_integration | 
| OLD | NEW | 
|---|