Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Unified Diff: chrome/browser/shell_integration_win.cc

Issue 1832853003: DefaultBrowserWorker now fully supports opening the settings for Win10 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« chrome/browser/shell_integration.cc ('K') | « chrome/browser/shell_integration.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/shell_integration_win.cc
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc
index fc5cba989436839de7119bfec218bc053154bccc..76051691c945119ca8c4ea5a7b634f6031a980be 100644
--- a/chrome/browser/shell_integration_win.cc
+++ b/chrome/browser/shell_integration_win.cc
@@ -16,11 +16,13 @@
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/macros.h"
+#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/timer/timer.h"
#include "base/win/registry.h"
#include "base/win/scoped_comptr.h"
#include "base/win/scoped_propvariant.h"
@@ -215,6 +217,105 @@ DefaultWebClientState GetDefaultWebClientStateFromShellUtilDefaultState(
}
}
+bool IsSetAsDefaultUsingSystemSettings() {
+ return base::win::GetVersion() >= base::win::VERSION_WIN10;
+}
+
+// There is no way to make sure the user is done with the system settings, but a
+// signal that the interaction is finished is needed for UMA. A timer of 2
+// minutes is used as a substitute. The registry values for default browser is
+// also monitored (http and https association) to signal the end of the
+// interaction early when it is clear that the user made a choice.
+//
+// This helper class manages both the timer and the registry watchers and make
grt (UTC plus 2) 2016/03/29 16:45:03 nit: make -> makes
Patrick Monette 2016/03/29 17:43:08 Done.
+// sure the callback for the end of the settings interaction is only run once.
+class OpenSystemSettingsHelper
+ : public base::RefCounted<OpenSystemSettingsHelper> {
+ public:
+ OpenSystemSettingsHelper() {}
+
+ // Initializes the timer and the registry watcher.
+ void Initialize(
+ base::Callback<void(bool)> conclude_settings_interaction_callback) {
+ const wchar_t url_association_format[] =
+ L"SOFTWARE\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\"
+ L"%ls\\UserChoice";
+ http_registry_key_ = CreateRegistryKeyWatcher(
+ base::StringPrintf(url_association_format, L"http").c_str(),
+ conclude_settings_interaction_callback);
+ https_registry_key_ = CreateRegistryKeyWatcher(
+ base::StringPrintf(url_association_format, L"https").c_str(),
+ conclude_settings_interaction_callback);
+
+ timer_.Start(FROM_HERE, base::TimeDelta::FromMinutes(2),
+ base::Bind(conclude_settings_interaction_callback, false));
+ }
+
+ // Either the timer or the registry watcher signaled the end of the
+ // interaction. Make sure the other signal is ignored.
+ void Clear() {
+ run_once_ = false;
+ timer_.Reset();
+ http_registry_key_.reset();
+ https_registry_key_.reset();
+ }
+
+ void IncrementRegistryWatcherCount() { registry_watcher_count_++; }
+
+ const bool run_once() { return run_once_; }
+ const int get_registry_watcher_count() { return registry_watcher_count_; }
+
+ private:
+ scoped_ptr<base::win::RegKey> CreateRegistryKeyWatcher(
+ const wchar_t* registry_value,
+ base::Callback<void(bool)> conclude_settings_interaction_callback) {
+ scoped_ptr<base::win::RegKey> reg_key(
+ new base::win::RegKey(HKEY_CURRENT_USER, registry_value, KEY_READ));
+
+ if (reg_key && reg_key->Valid()) {
grt (UTC plus 2) 2016/03/29 16:45:03 no need to test reg_key alone since it will always
Patrick Monette 2016/03/29 17:43:08 Done.
+ reg_key->StartWatching(
+ base::Bind(conclude_settings_interaction_callback, true));
+ }
+ return reg_key;
+ }
+
+ base::OneShotTimer timer_;
+ scoped_ptr<base::win::RegKey> http_registry_key_;
+ scoped_ptr<base::win::RegKey> https_registry_key_;
+
+ // Used to make sure only one of the timer or the registry watcher's signal is
+ // taken in consideration.
+ bool run_once_ = true;
+
+ // The number of time a registry key watcher fired.
+ int registry_watcher_count_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(OpenSystemSettingsHelper);
+};
+
+void ConcludeOpenSystemSettingsToDefaultBrowser(
grt (UTC plus 2) 2016/03/29 16:45:03 this function is tightly coupled to the helper. ca
Patrick Monette 2016/03/29 17:43:08 Done.
+ scoped_refptr<OpenSystemSettingsHelper> helper,
+ base::Callback<void()> on_finished_callback,
grt (UTC plus 2) 2016/03/29 16:45:03 const base::Closure&
Patrick Monette 2016/03/29 17:43:08 Done.
+ bool is_registry_watcher) {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+ DCHECK(helper);
+
+ // It is possible to get here if only one of the http/https url association
+ // was changed, which is not enough for GetDefaultBrowser() to return
+ // IS_DEFAULT.
+ if (is_registry_watcher) {
+ helper->IncrementRegistryWatcherCount();
+ if (helper->get_registry_watcher_count() != 2)
+ return;
+ }
+
+ if (!helper->run_once())
+ return;
+ helper->Clear();
+
+ on_finished_callback.Run();
+}
+
} // namespace
bool SetAsDefaultBrowser() {
@@ -253,6 +354,24 @@ bool SetAsDefaultBrowserInteractive() {
return true;
}
+void SetAsDefaultBrowserUsingSystemSettings(
+ base::Closure on_finished_callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+
+ scoped_refptr<OpenSystemSettingsHelper> helper(new OpenSystemSettingsHelper);
+ helper->Initialize(base::Bind(&ConcludeOpenSystemSettingsToDefaultBrowser,
+ helper, on_finished_callback));
+
+ base::FilePath chrome_exe;
+ if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
+ NOTREACHED() << "Error getting app exe path";
+ return;
+ }
+
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ ShellUtil::ShowMakeChromeDefaultSystemUI(dist, chrome_exe);
+}
+
bool SetAsDefaultProtocolClient(const std::string& protocol) {
if (protocol.empty())
return false;
@@ -302,6 +421,8 @@ DefaultWebClientSetPermission CanSetAsDefaultBrowser() {
return SET_DEFAULT_NOT_ALLOWED;
if (ShellUtil::CanMakeChromeDefaultUnattended())
return SET_DEFAULT_UNATTENDED;
+ if (IsSetAsDefaultUsingSystemSettings())
+ return SET_DEFAULT_OPEN_SETTINGS;
return SET_DEFAULT_INTERACTIVE;
}
« chrome/browser/shell_integration.cc ('K') | « chrome/browser/shell_integration.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698