Skip to content

Commit b87aa19

Browse files
committed
Bug 1862450 - Made installer changes for dual browser extension r=mhughes
Differential Revision: https://phabricator.services.mozilla.com/D192478
1 parent ed12e0d commit b87aa19

File tree

6 files changed

+228
-0
lines changed

6 files changed

+228
-0
lines changed

browser/app/profile/firefox.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ pref("browser.shell.checkDefaultPDF.silencedByUser", false);
298298
// URL to navigate to when launching Firefox after accepting the Windows Default
299299
// Browser Agent "Set Firefox as default" call to action.
300300
pref("browser.shell.defaultBrowserAgent.thanksURL", "https://www.mozilla.org/%LOCALE%/firefox/set-as-default/thanks/");
301+
// Whether or not we want to run through the early startup idle task
302+
// which registers the firefox and firefox-private registry keys.
303+
pref("browser.shell.customProtocolsRegistered", false);
301304
#endif
302305

303306

browser/components/BrowserContentHandler.sys.mjs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,25 @@ function shouldLoadURI(aURI) {
6161
}
6262

6363
function resolveURIInternal(aCmdLine, aArgument) {
64+
// If using Firefox protocol handler remove it from URI
65+
// at this stage. This is before we would otherwise
66+
// record telemetry so do that here.
67+
if (aArgument.startsWith("firefox:")) {
68+
aArgument = aArgument.substring("firefox:".length);
69+
Services.telemetry.keyedScalarAdd(
70+
"os.environment.launched_to_handle",
71+
"firefox",
72+
1
73+
);
74+
}
75+
if (aArgument.startsWith("firefox-private:")) {
76+
aArgument = aArgument.substring("firefox-private:".length);
77+
Services.telemetry.keyedScalarAdd(
78+
"os.environment.launched_to_handle",
79+
"firefox-private",
80+
1
81+
);
82+
}
6483
var uri = aCmdLine.resolveURI(aArgument);
6584
var uriFixup = Services.uriFixup;
6685

browser/components/BrowserGlue.sys.mjs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2609,6 +2609,130 @@ BrowserGlue.prototype = {
26092609
},
26102610
},
26112611

2612+
{
2613+
name: "dualBrowserProtocolHandler",
2614+
condition:
2615+
AppConstants.platform == "win" &&
2616+
!Services.prefs.getBoolPref(
2617+
"browser.shell.customProtocolsRegistered"
2618+
),
2619+
task: async () => {
2620+
const FIREFOX_HANDLER_NAME = "firefox";
2621+
const FIREFOX_PRIVATE_HANDLER_NAME = "firefox-private";
2622+
const path = Services.dirsvc.get("XREExeF", Ci.nsIFile).path;
2623+
let wrk = Cc["@mozilla.org/windows-registry-key;1"].createInstance(
2624+
Ci.nsIWindowsRegKey
2625+
);
2626+
try {
2627+
wrk.open(wrk.ROOT_KEY_CLASSES_ROOT, "", wrk.ACCESS_READ);
2628+
let FxSet = wrk.hasChild(FIREFOX_HANDLER_NAME);
2629+
let FxPrivateSet = wrk.hasChild(FIREFOX_PRIVATE_HANDLER_NAME);
2630+
wrk.close();
2631+
if (FxSet && FxPrivateSet) {
2632+
return;
2633+
}
2634+
wrk.open(
2635+
wrk.ROOT_KEY_CURRENT_USER,
2636+
"Software\\Classes",
2637+
wrk.ACCESS_ALL
2638+
);
2639+
const maybeUpdateRegistry = (
2640+
isSetAlready,
2641+
handler,
2642+
protocolName
2643+
) => {
2644+
let retVal = false;
2645+
if (isSetAlready) {
2646+
return true;
2647+
}
2648+
let FxKey = wrk.createChild(handler, wrk.ACCESS_ALL);
2649+
try {
2650+
// Write URL protocol key
2651+
FxKey.writeStringValue("", protocolName);
2652+
FxKey.writeStringValue("URL Protocol", "");
2653+
FxKey.close();
2654+
// Write defaultIcon key
2655+
FxKey.create(
2656+
FxKey.ROOT_KEY_CURRENT_USER,
2657+
"Software\\Classes\\" + handler + "\\DefaultIcon",
2658+
FxKey.ACCESS_ALL
2659+
);
2660+
FxKey.open(
2661+
FxKey.ROOT_KEY_CURRENT_USER,
2662+
"Software\\Classes\\" + handler + "\\DefaultIcon",
2663+
FxKey.ACCESS_ALL
2664+
);
2665+
FxKey.writeStringValue("", `\"${path}\",1`);
2666+
FxKey.close();
2667+
// Write shell\\open\\command key
2668+
FxKey.create(
2669+
FxKey.ROOT_KEY_CURRENT_USER,
2670+
"Software\\Classes\\" + handler + "\\shell",
2671+
FxKey.ACCESS_ALL
2672+
);
2673+
FxKey.create(
2674+
FxKey.ROOT_KEY_CURRENT_USER,
2675+
"Software\\Classes\\" + handler + "\\shell\\open",
2676+
FxKey.ACCESS_ALL
2677+
);
2678+
FxKey.create(
2679+
FxKey.ROOT_KEY_CURRENT_USER,
2680+
"Software\\Classes\\" + handler + "\\shell\\open\\command",
2681+
FxKey.ACCESS_ALL
2682+
);
2683+
FxKey.open(
2684+
FxKey.ROOT_KEY_CURRENT_USER,
2685+
"Software\\Classes\\" + handler + "\\shell\\open\\command",
2686+
FxKey.ACCESS_ALL
2687+
);
2688+
if (handler == FIREFOX_PRIVATE_HANDLER_NAME) {
2689+
FxKey.writeStringValue(
2690+
"",
2691+
`\"${path}\" -osint -private-window \"%1\"`
2692+
);
2693+
} else {
2694+
FxKey.writeStringValue("", `\"${path}\" -osint -url \"%1\"`);
2695+
}
2696+
retVal = true;
2697+
} catch (ex) {
2698+
retVal = false;
2699+
console.log(ex);
2700+
} finally {
2701+
FxKey.close();
2702+
}
2703+
return retVal;
2704+
};
2705+
try {
2706+
FxSet = maybeUpdateRegistry(
2707+
FxSet,
2708+
FIREFOX_HANDLER_NAME,
2709+
"URL:Firefox Protocol"
2710+
);
2711+
} catch (ex) {
2712+
console.log(ex);
2713+
}
2714+
try {
2715+
FxPrivateSet = maybeUpdateRegistry(
2716+
FxPrivateSet,
2717+
FIREFOX_PRIVATE_HANDLER_NAME,
2718+
"URL:Firefox Private Browsing Protocol"
2719+
);
2720+
} catch (ex) {
2721+
console.log(ex);
2722+
}
2723+
Services.prefs.setBoolPref(
2724+
"browser.shell.customProtocolsRegistered",
2725+
FxSet && FxPrivateSet
2726+
);
2727+
} catch (ex) {
2728+
console.log(ex);
2729+
} finally {
2730+
wrk.close();
2731+
}
2732+
},
2733+
timeout: 5000,
2734+
},
2735+
26122736
// Ensure a Private Browsing Shortcut exists. This is needed in case
26132737
// a user tries to use Windows functionality to pin our Private Browsing
26142738
// mode icon to the Taskbar (eg: the "Pin to Taskbar" context menu item).

browser/installer/windows/msix/AppxManifest.xml.in

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@
9191
<uap:Logo>Assets\Document44x44.png</uap:Logo>
9292
</uap3:Protocol>
9393
</uap3:Extension>
94+
<uap3:Extension Category="windows.protocol">
95+
<uap3:Protocol Name="firefox" Parameters="-osint -url &quot;%1&quot;">
96+
<uap:DisplayName>Firefox Protocol</uap:DisplayName>
97+
<uap:Logo>Assets\Document44x44.png</uap:Logo>
98+
</uap3:Protocol>
99+
</uap3:Extension>
100+
<uap3:Extension Category="windows.protocol">
101+
<uap3:Protocol Name="firefox-private" Parameters="-osint -private-window &quot;%1&quot;">
102+
<uap:DisplayName>Firefox Private Browsing Protocol</uap:DisplayName>
103+
<uap:Logo>Assets\Document44x44.png</uap:Logo>
104+
</uap3:Protocol>
105+
</uap3:Extension>
94106
<!-- COM registrations for the notification server. -->
95107
<com:Extension Category="windows.comServer">
96108
<com:ComServer>

browser/installer/windows/nsis/installer.nsi

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,25 @@ Section "-Application" APP_IDX
474474
${AddDisabledDDEHandlerValues} "FirefoxURL-$AppUserModelID" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
475475
"${AppRegName} URL" "true"
476476

477+
; Create protocol registry keys for dual browser extensions - only if not already set
478+
SetShellVarContext current ; Set SHCTX to HKCU
479+
!define FIREFOX_PROTOCOL "firefox"
480+
ClearErrors
481+
ReadRegStr $0 SHCTX "Software\Classes\${FIREFOX_PROTOCOL}" ""
482+
${If} $0 == ""
483+
${AddDisabledDDEHandlerValues} "${FIREFOX_PROTOCOL}" "$\"$INSTDIR\${FileMainEXE}$\" -osint -url $\"%1$\"" \
484+
"$8,${IDI_APPICON_ZERO_BASED}" "Firefox Browsing Protocol" "true"
485+
${EndIf}
486+
487+
!define FIREFOX_PRIVATE_PROTOCOL "firefox-private"
488+
ClearErrors
489+
ReadRegStr $0 SHCTX "Software\Classes\${FIREFOX_PRIVATE_PROTOCOL}" ""
490+
${If} $0 == ""
491+
${AddDisabledDDEHandlerValues} "${FIREFOX_PRIVATE_PROTOCOL}" "$\"$INSTDIR\${FileMainEXE}$\" -osint -private-window $\"%1$\"" \
492+
"$8,${IDI_PBICON_PB_EXE_ZERO_BASED}" "Firefox Private Browsing Protocol" "true"
493+
${EndIf}
494+
SetShellVarContext all ; Set SHCTX to HKLM
495+
477496
; The keys below can be set in HKCU if needed.
478497
${If} $TmpVal == "HKLM"
479498
; Set the Start Menu Internet and Registered App HKLM registry keys.

browser/installer/windows/nsis/uninstaller.nsi

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,52 @@ SectionEnd
411411
################################################################################
412412
# Uninstall Sections
413413

414+
/**
415+
* Deletes the registry keys for a protocol handler but only if those registry
416+
* keys were pointed to the installation being uninstalled.
417+
* Does this with both the HKLM and the HKCU registry entries.
418+
*
419+
* @param _PROTOCOL
420+
* The protocol to delete the registry keys for
421+
*/
422+
!macro DeleteProtocolRegistryIfSetToInstallation _PROTOCOL
423+
Push $0
424+
425+
; Check if there is a protocol handler registered by fetching the DefaultIcon value
426+
; in the registry.
427+
; If there is something registered for the icon, it will be the path to the executable,
428+
; plus a comma and a number for the id of the resource for the icon.
429+
; Use StrCpy with -2 to remove the comma and the resource id so that
430+
; the whole path to the executable can be compared against what's being
431+
; uninstalled.
432+
433+
; Do all of that twice, once for the local machine and once for the current user
434+
435+
; Remove protocol handlers
436+
ClearErrors
437+
ReadRegStr $0 HKLM "Software\Classes\${_PROTOCOL}\DefaultIcon" ""
438+
${If} $0 != ""
439+
StrCpy $0 $0 -2
440+
${If} $0 == "$INSTDIR\${FileMainEXE}"
441+
DeleteRegKey HKLM "Software\Classes\${_PROTOCOL}"
442+
${EndIf}
443+
${EndIf}
444+
445+
ClearErrors
446+
ReadRegStr $0 HKCU "Software\Classes\${_PROTOCOL}\DefaultIcon" ""
447+
${If} $0 != ""
448+
StrCpy $0 $0 -2
449+
${If} $0 == "$INSTDIR\${FileMainEXE}"
450+
DeleteRegKey HKCU "Software\Classes\${_PROTOCOL}"
451+
${EndIf}
452+
${EndIf}
453+
454+
ClearErrors
455+
456+
Pop $0
457+
!macroend
458+
!define DeleteProtocolRegistryIfSetToInstallation '!insertmacro DeleteProtocolRegistryIfSetToInstallation'
459+
414460
Section "Uninstall"
415461
SetDetailsPrint textonly
416462
DetailPrint $(STATUS_UNINSTALL_MAIN)
@@ -522,6 +568,11 @@ Section "Uninstall"
522568

523569
; Clean up "launch on login" registry key for this installation.
524570
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "Mozilla-${AppName}-$AppUserModelID"
571+
572+
; Remove dual browser extension protocol handlers
573+
${DeleteProtocolRegistryIfSetToInstallation} "firefox"
574+
${DeleteProtocolRegistryIfSetToInstallation} "firefox-private"
575+
525576
; Remove old protocol handler and StartMenuInternet keys without install path
526577
; hashes, but only if they're for this installation. We've never supported
527578
; bare FirefoxPDF.

0 commit comments

Comments
 (0)