mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1731898 - Change protocol handling logic for non-standard cases r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D141859
This commit is contained in:
parent
6e2c6b51eb
commit
096901dbf5
@ -111,6 +111,8 @@ const kSafeSchemes = [
|
||||
"xmpp",
|
||||
];
|
||||
|
||||
const STANDARD_SAFE_PROTOCOLS = kSafeSchemes;
|
||||
|
||||
// Note that even if the scheme fits the criteria for a web-handled scheme
|
||||
// (ie it is compatible with the checks registerProtocolHandler uses), it may
|
||||
// not be web-handled - it could still be handled via the OS by another app.
|
||||
@ -275,6 +277,7 @@ var E10SUtils = {
|
||||
PRIVILEGEDMOZILLA_REMOTE_TYPE,
|
||||
FISSION_WEB_REMOTE_TYPE,
|
||||
SERVICEWORKER_REMOTE_TYPE,
|
||||
STANDARD_SAFE_PROTOCOLS,
|
||||
|
||||
/**
|
||||
* @param aURI The URI of the about page
|
||||
|
@ -8,6 +8,9 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
const { E10SUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/E10SUtils.jsm"
|
||||
);
|
||||
|
||||
const DIALOG_URL_APP_CHOOSER =
|
||||
"chrome://mozapps/content/handling/appChooser.xhtml";
|
||||
@ -310,12 +313,14 @@ class nsContentDispatchChooser {
|
||||
}
|
||||
|
||||
let shouldOpenHandler = false;
|
||||
|
||||
try {
|
||||
shouldOpenHandler = await this._prompt(
|
||||
aHandler,
|
||||
aPrincipal,
|
||||
callerHasPermission,
|
||||
aBrowsingContext
|
||||
aBrowsingContext,
|
||||
aURI
|
||||
);
|
||||
} catch (error) {
|
||||
Cu.reportError(error.message);
|
||||
@ -358,9 +363,31 @@ class nsContentDispatchChooser {
|
||||
* @param {BrowsingContext} [aBrowsingContext] - Context associated with the
|
||||
* protocol navigation.
|
||||
*/
|
||||
async _prompt(aHandler, aPrincipal, aHasPermission, aBrowsingContext) {
|
||||
async _prompt(aHandler, aPrincipal, aHasPermission, aBrowsingContext, aURI) {
|
||||
let shouldOpenHandler = false;
|
||||
let resetHandlerChoice = false;
|
||||
let updateHandlerData = false;
|
||||
|
||||
const isStandardProtocol = E10SUtils.STANDARD_SAFE_PROTOCOLS.includes(
|
||||
aURI.scheme
|
||||
);
|
||||
const {
|
||||
hasDefaultHandler,
|
||||
preferredApplicationHandler,
|
||||
alwaysAskBeforeHandling,
|
||||
} = aHandler;
|
||||
|
||||
// This will skip the app chooser dialog flow unless the user explicitly opts to choose
|
||||
// another app in the permission dialog.
|
||||
if (
|
||||
!isStandardProtocol &&
|
||||
hasDefaultHandler &&
|
||||
preferredApplicationHandler == null &&
|
||||
alwaysAskBeforeHandling
|
||||
) {
|
||||
aHandler.alwaysAskBeforeHandling = false;
|
||||
updateHandlerData = true;
|
||||
}
|
||||
|
||||
// If caller does not have permission, prompt the user.
|
||||
if (!aHasPermission) {
|
||||
@ -446,14 +473,17 @@ class nsContentDispatchChooser {
|
||||
]) {
|
||||
aHandler[prop] = outArgs.getProperty(prop);
|
||||
}
|
||||
|
||||
// Store handler data
|
||||
Cc["@mozilla.org/uriloader/handler-service;1"]
|
||||
.getService(Ci.nsIHandlerService)
|
||||
.store(aHandler);
|
||||
updateHandlerData = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateHandlerData) {
|
||||
// Store handler data
|
||||
Cc["@mozilla.org/uriloader/handler-service;1"]
|
||||
.getService(Ci.nsIHandlerService)
|
||||
.store(aHandler);
|
||||
}
|
||||
|
||||
return shouldOpenHandler;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var { AppConstants } = ChromeUtils.import(
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
|
||||
let gHandlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(
|
||||
Ci.nsIHandlerService
|
||||
);
|
||||
@ -71,7 +75,6 @@ function initTestHandlers() {
|
||||
let handlerInfo = HandlerServiceTestUtils.getBlankHandlerInfo(scheme);
|
||||
handlerInfo.possibleApplicationHandlers.appendElement(webHandler);
|
||||
handlerInfo.preferredApplicationHandler = webHandler;
|
||||
|
||||
gHandlerService.store(handlerInfo);
|
||||
});
|
||||
}
|
||||
@ -128,6 +131,7 @@ async function triggerOpenProto(
|
||||
useJSRedirect = false,
|
||||
serverRedirect = "",
|
||||
linkToRedirect = false,
|
||||
customHandlerInfo,
|
||||
} = {}
|
||||
) {
|
||||
let uri = `${scheme}://test`;
|
||||
@ -169,7 +173,8 @@ async function triggerOpenProto(
|
||||
"@mozilla.org/content-dispatch-chooser;1"
|
||||
].createInstance(Ci.nsIContentDispatchChooser);
|
||||
|
||||
let handler = HandlerServiceTestUtils.getHandlerInfo(scheme);
|
||||
let handler =
|
||||
customHandlerInfo || HandlerServiceTestUtils.getHandlerInfo(scheme);
|
||||
|
||||
contentDispatchChooser.handleURI(
|
||||
handler,
|
||||
@ -328,6 +333,7 @@ async function testOpenProto(
|
||||
// Check the button label depending on whether we would show the chooser
|
||||
// dialog next or directly open the handler.
|
||||
let acceptBtnLabel = dialogEl.getButton("accept")?.label;
|
||||
|
||||
if (chooserIsNext) {
|
||||
is(
|
||||
acceptBtnLabel,
|
||||
@ -832,6 +838,37 @@ add_task(async function test_no_principal() {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that if a URI scheme has a non-standard protocol, an OS default exists,
|
||||
* and the user hasn't selected an alternative only the permission dialog is shown.
|
||||
*/
|
||||
add_task(async function test_non_standard_protocol() {
|
||||
let scheme = null;
|
||||
// TODO add a scheme for Windows 10 or greater once support is added (see bug 1764599).
|
||||
if (AppConstants.platform == "macosx") {
|
||||
scheme = "itunes";
|
||||
} else {
|
||||
info(
|
||||
"Skipping this test since there isn't a suitable default protocol on this platform"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await BrowserTestUtils.withNewTab(ORIGIN1, async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
customHandlerInfo: HandlerServiceTestUtils.getHandlerInfo(scheme),
|
||||
},
|
||||
permDialogOptions: {
|
||||
hasCheckbox: true,
|
||||
hasChangeApp: true,
|
||||
chooserIsNext: false,
|
||||
actionChangeApp: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that we skip the permission dialog for extension callers.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user