Bug 1167294 - Launch the modern Settings app when setting the default browser on Windows 10. r=jimm,Gijs
authorJared Wein <jwein@mozilla.com>
Wed, 03 Jun 2015 11:40:40 -0400
changeset 247123 afdd2579f9380967a0fd1912eb5aeecbc7b50947
parent 247122 a4c0703e9a107ce9ec67cb6ea175ba19c5e77bed
child 247124 9daecda7080dc4b69d742ea441356ed52751ae22
push id60612
push userryanvm@gmail.com
push dateThu, 04 Jun 2015 13:28:04 +0000
treeherdermozilla-inbound@dbc89e025b5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, Gijs
bugs1167294
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1167294 - Launch the modern Settings app when setting the default browser on Windows 10. r=jimm,Gijs
browser/components/nsBrowserGlue.js
browser/components/preferences/in-content/main.js
browser/components/shell/nsWindowsShellService.cpp
browser/components/shell/nsWindowsShellService.h
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2621,26 +2621,26 @@ let DefaultBrowserCheck = {
   closePrompt: function(aNode) {
     if (this._notification) {
       this._notification.close();
     }
   },
 
   setAsDefault: function() {
     let claimAllTypes = true;
-#ifdef XP_WIN
-    try {
-      // In Windows 8, the UI for selecting default protocol is much
-      // nicer than the UI for setting file type associations. So we
-      // only show the protocol association screen on Windows 8.
-      // Windows 8 is version 6.2.
-      let version = Services.sysinfo.getProperty("version");
-      claimAllTypes = (parseFloat(version) < 6.2);
-    } catch (ex) { }
-#endif
+    if (AppConstants.platform == "win") {
+      try {
+        // In Windows 8+, the UI for selecting default protocol is much
+        // nicer than the UI for setting file type associations. So we
+        // only show the protocol association screen on Windows 8+.
+        // Windows 8 is version 6.2.
+        let version = Services.sysinfo.getProperty("version");
+        claimAllTypes = (parseFloat(version) < 6.2);
+      } catch (ex) { }
+    }
     try {
       ShellService.setDefaultBrowser(claimAllTypes, false);
     } catch (ex) {
       Cu.reportError(ex);
     }
   },
 
   _createPopup: function(win, notNowStrings, neverStrings) {
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -708,17 +708,26 @@ var gMainPane = {
    * Set browser as the operating system default browser.
    */
   setDefaultBrowser: function()
   {
     let shellSvc = getShellService();
     if (!shellSvc)
       return;
     try {
-      shellSvc.setDefaultBrowser(true, false);
+      let claimAllTypes = true;
+      if (AppConstants.platform == "win") {
+        // In Windows 8+, the UI for selecting default protocol is much
+        // nicer than the UI for setting file type associations. So we
+        // only show the protocol association screen on Windows 8+.
+        // Windows 8 is version 6.2.
+        let version = Services.sysinfo.getProperty("version");
+        claimAllTypes = (parseFloat(version) < 6.2);
+      }
+      shellSvc.setDefaultBrowser(claimAllTypes, false);
     } catch (ex) {
       Cu.reportError(ex);
       return;
     }
     let selectedIndex =
       shellSvc.isDefaultBrowser(false, true) ? 1 : 0;
     document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
   }
--- a/browser/components/shell/nsWindowsShellService.cpp
+++ b/browser/components/shell/nsWindowsShellService.cpp
@@ -34,16 +34,19 @@
 #include "windows.h"
 #include "shellapi.h"
 
 #ifdef _WIN32_WINNT
 #undef _WIN32_WINNT
 #endif
 #define _WIN32_WINNT 0x0600
 #define INITGUID
+#undef NTDDI_VERSION
+#define NTDDI_VERSION NTDDI_WIN8
+// Needed for access to IApplicationActivationManager
 #include <shlobj.h>
 
 #include <mbstring.h>
 #include <shlwapi.h>
 
 #ifndef MAX_BUF
 #define MAX_BUF 4096
 #endif
@@ -658,16 +661,38 @@ nsWindowsShellService::LaunchControlPane
   }
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);
 
   return NS_OK;
 }
 
 nsresult
+nsWindowsShellService::LaunchModernSettingsDialogDefaultApps()
+{
+  IApplicationActivationManager* pActivator;
+  HRESULT hr = CoCreateInstance(CLSID_ApplicationActivationManager,
+                                nullptr,
+                                CLSCTX_INPROC,
+                                IID_IApplicationActivationManager,
+                                (void**)&pActivator);
+
+  if (SUCCEEDED(hr)) {
+    DWORD pid;
+    hr = pActivator->ActivateApplication(
+           L"windows.immersivecontrolpanel_cw5n1h2txyewy"
+           L"!microsoft.windows.immersivecontrolpanel",
+           L"page=SettingsPageAppsDefaults", AO_NONE, &pid);
+    pActivator->Release();
+    return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
+
+nsresult
 nsWindowsShellService::LaunchHTTPHandlerPane()
 {
   OPENASINFO info;
   info.pcszFile = L"http";
   info.pcszClass = nullptr;
   info.oaifInFlags = OAIF_FORCE_REGISTRATION | 
                      OAIF_URL_PROTOCOL |
                      OAIF_REGISTER_EXT;
@@ -692,19 +717,27 @@ nsWindowsShellService::SetDefaultBrowser
     if (aClaimAllTypes) {
       rv = LaunchControlPanelDefaultPrograms();
       // The above call should never really fail, but just in case
       // fall back to showing the HTTP association screen only.
       if (NS_FAILED(rv)) {
         rv = LaunchHTTPHandlerPane();
       }
     } else {
-      rv = LaunchHTTPHandlerPane();
-      // The above calls hould never really fail, but just in case
-      // fallb ack to showing control panel for all defaults
+      // Windows 10 blocks attempts to load the HTTP Handler
+      // association dialog, so the modern Settings dialog
+      // is opened with the Default Apps view loaded.
+      if (IsWin10OrLater()) {
+        rv = LaunchModernSettingsDialogDefaultApps();
+      } else {
+        rv = LaunchHTTPHandlerPane();
+      }
+
+      // The above call should never really fail, but just in case
+      // fall back to showing control panel for all defaults
       if (NS_FAILED(rv)) {
         rv = LaunchControlPanelDefaultPrograms();
       }
     }
   }
 
   nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (prefs) {
--- a/browser/components/shell/nsWindowsShellService.h
+++ b/browser/components/shell/nsWindowsShellService.h
@@ -23,15 +23,16 @@ public:
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISHELLSERVICE
   NS_DECL_NSIWINDOWSSHELLSERVICE
 
 protected:
   bool IsDefaultBrowserVista(bool aCheckAllTypes, bool* aIsDefaultBrowser);
   nsresult LaunchControlPanelDefaultPrograms();
+  nsresult LaunchModernSettingsDialogDefaultApps();
   nsresult LaunchHTTPHandlerPane();
 
 private:
   bool      mCheckedThisSession;
 };
 
 #endif // nswindowsshellservice_h____