зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1561079 - Add a `GeckoSession.loadUri()` overload that takes a referring `GeckoSession` r=geckoview-reviewers,ckerschb,esawin,agi
Differential Revision: https://phabricator.services.mozilla.com/D36526 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
b9f7851a27
Коммит
4274c61812
|
@ -427,6 +427,7 @@ package org.mozilla.geckoview {
|
||||||
method @AnyThread public void loadUri(@NonNull String);
|
method @AnyThread public void loadUri(@NonNull String);
|
||||||
method @AnyThread public void loadUri(@NonNull String, int);
|
method @AnyThread public void loadUri(@NonNull String, int);
|
||||||
method @AnyThread public void loadUri(@NonNull String, @Nullable String, int);
|
method @AnyThread public void loadUri(@NonNull String, @Nullable String, int);
|
||||||
|
method @AnyThread public void loadUri(@NonNull String, @Nullable GeckoSession, int);
|
||||||
method @AnyThread public void loadUri(@NonNull Uri);
|
method @AnyThread public void loadUri(@NonNull Uri);
|
||||||
method @AnyThread public void loadUri(@NonNull Uri, int);
|
method @AnyThread public void loadUri(@NonNull Uri, int);
|
||||||
method @AnyThread public void loadUri(@NonNull Uri, @Nullable Uri, int);
|
method @AnyThread public void loadUri(@NonNull Uri, @Nullable Uri, int);
|
||||||
|
|
|
@ -1174,6 +1174,40 @@ class NavigationDelegateTest : BaseSessionTest() {
|
||||||
equalTo(referrer))
|
equalTo(referrer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun loadUriReferrerSession() {
|
||||||
|
val uri = "https://example.com/bar"
|
||||||
|
val referrer = "https://example.org/foo"
|
||||||
|
|
||||||
|
sessionRule.session.loadUri(referrer)
|
||||||
|
sessionRule.session.waitForPageStop()
|
||||||
|
|
||||||
|
val newSession = sessionRule.createOpenSession()
|
||||||
|
newSession.loadUri(uri, sessionRule.session, GeckoSession.LOAD_FLAGS_NONE)
|
||||||
|
newSession.waitForPageStop()
|
||||||
|
|
||||||
|
assertThat("Referrer should match",
|
||||||
|
newSession.evaluateJS("document.referrer") as String,
|
||||||
|
equalTo(referrer))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun loadUriReferrerSessionFileUrl() {
|
||||||
|
val uri = "file:///system/etc/fonts.xml"
|
||||||
|
val referrer = "https://example.org"
|
||||||
|
|
||||||
|
sessionRule.session.loadUri(referrer)
|
||||||
|
sessionRule.session.waitForPageStop()
|
||||||
|
|
||||||
|
val newSession = sessionRule.createOpenSession()
|
||||||
|
newSession.loadUri(uri, sessionRule.session, GeckoSession.LOAD_FLAGS_NONE)
|
||||||
|
newSession.waitUntilCalled(object : Callbacks.NavigationDelegate {
|
||||||
|
@AssertCalled
|
||||||
|
override fun onLoadError(session: GeckoSession, uri: String?, error: WebRequestError): GeckoResult<String>? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test(expected = GeckoResult.UncaughtException::class)
|
@Test(expected = GeckoResult.UncaughtException::class)
|
||||||
fun onNewSession_doesNotAllowOpened() {
|
fun onNewSession_doesNotAllowOpened() {
|
||||||
// Disable popup blocker.
|
// Disable popup blocker.
|
||||||
|
|
|
@ -1537,7 +1537,7 @@ public class GeckoSession implements Parcelable {
|
||||||
*/
|
*/
|
||||||
@AnyThread
|
@AnyThread
|
||||||
public void loadUri(final @NonNull String uri) {
|
public void loadUri(final @NonNull String uri) {
|
||||||
loadUri(uri, null, LOAD_FLAGS_NONE);
|
loadUri(uri, (GeckoSession)null, LOAD_FLAGS_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1548,7 +1548,7 @@ public class GeckoSession implements Parcelable {
|
||||||
*/
|
*/
|
||||||
@AnyThread
|
@AnyThread
|
||||||
public void loadUri(final @NonNull String uri, final @LoadFlags int flags) {
|
public void loadUri(final @NonNull String uri, final @LoadFlags int flags) {
|
||||||
loadUri(uri, null, flags);
|
loadUri(uri, (GeckoSession)null, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1566,7 +1566,29 @@ public class GeckoSession implements Parcelable {
|
||||||
msg.putInt("flags", flags);
|
msg.putInt("flags", flags);
|
||||||
|
|
||||||
if (referrer != null) {
|
if (referrer != null) {
|
||||||
msg.putString("referrer", referrer);
|
msg.putString("referrerUri", referrer);
|
||||||
|
}
|
||||||
|
mEventDispatcher.dispatch("GeckoView:LoadUri", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the given URI with the specified referrer and load type. This method will also do any
|
||||||
|
* applicable checks to ensure that the specified URI is both safe and allowable
|
||||||
|
* according to the referring GeckoSession.
|
||||||
|
*
|
||||||
|
* @param uri the URI to load
|
||||||
|
* @param referrer the referring GeckoSession, may be null
|
||||||
|
* @param flags the load flags to use, an OR-ed value of {@link #LOAD_FLAGS_NONE LOAD_FLAGS_*}
|
||||||
|
*/
|
||||||
|
@AnyThread
|
||||||
|
public void loadUri(final @NonNull String uri, final @Nullable GeckoSession referrer,
|
||||||
|
final @LoadFlags int flags) {
|
||||||
|
final GeckoBundle msg = new GeckoBundle();
|
||||||
|
msg.putString("uri", uri);
|
||||||
|
msg.putInt("flags", flags);
|
||||||
|
|
||||||
|
if (referrer != null) {
|
||||||
|
msg.putString("referrerSessionId", referrer.mId);
|
||||||
}
|
}
|
||||||
mEventDispatcher.dispatch("GeckoView:LoadUri", msg);
|
mEventDispatcher.dispatch("GeckoView:LoadUri", msg);
|
||||||
}
|
}
|
||||||
|
@ -1587,7 +1609,7 @@ public class GeckoSession implements Parcelable {
|
||||||
*/
|
*/
|
||||||
@AnyThread
|
@AnyThread
|
||||||
public void loadUri(final @NonNull Uri uri, final @LoadFlags int flags) {
|
public void loadUri(final @NonNull Uri uri, final @LoadFlags int flags) {
|
||||||
loadUri(uri.toString(), null, flags);
|
loadUri(uri.toString(), (GeckoSession)null, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1616,7 +1638,7 @@ public class GeckoSession implements Parcelable {
|
||||||
throw new IllegalArgumentException("data cannot be null");
|
throw new IllegalArgumentException("data cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
loadUri(createDataUri(data, mimeType), null, LOAD_FLAGS_NONE);
|
loadUri(createDataUri(data, mimeType), (GeckoSession)null, LOAD_FLAGS_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1632,7 +1654,7 @@ public class GeckoSession implements Parcelable {
|
||||||
throw new IllegalArgumentException("data cannot be null");
|
throw new IllegalArgumentException("data cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
loadUri(createDataUri(bytes, mimeType), null, LOAD_FLAGS_FORCE_ALLOW_DATA_URI);
|
loadUri(createDataUri(bytes, mimeType), (GeckoSession)null, LOAD_FLAGS_FORCE_ALLOW_DATA_URI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,6 +22,10 @@ exclude: true
|
||||||
manage opening/closing of the `GeckoSession` and instead leave that up to the app. It's also now allowed
|
manage opening/closing of the `GeckoSession` and instead leave that up to the app. It's also now allowed
|
||||||
to call `setSession` with a closed `GeckoSession`.
|
to call `setSession` with a closed `GeckoSession`.
|
||||||
|
|
||||||
|
- Added an overload of `GeckoSession.loadUri()` that accepts a referring `GeckoSession`. This should be used
|
||||||
|
when the URI we're loading originates from another page. A common example of this would be long pressing
|
||||||
|
a link and then opening that in a new `GeckoSession`.
|
||||||
|
|
||||||
## v69
|
## v69
|
||||||
- Modified behavior of ['setAutomaticFontSizeAdjustment'][69.1] so that it no
|
- Modified behavior of ['setAutomaticFontSizeAdjustment'][69.1] so that it no
|
||||||
longer has any effect on ['setFontInflationEnabled'][69.2]
|
longer has any effect on ['setFontInflationEnabled'][69.2]
|
||||||
|
@ -368,4 +372,4 @@ exclude: true
|
||||||
[65.24]: ../CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
|
[65.24]: ../CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
|
||||||
[65.25]: ../GeckoResult.html
|
[65.25]: ../GeckoResult.html
|
||||||
|
|
||||||
[api-version]: b51a187d4c36d7d0f4091d9d1227a553a4e08edb
|
[api-version]: d17e48f35d11ff368320919c6213e72d9f138da1
|
||||||
|
|
|
@ -105,7 +105,7 @@ class GeckoViewNavigation extends GeckoViewModule {
|
||||||
this.browser.gotoIndex(aData.index);
|
this.browser.gotoIndex(aData.index);
|
||||||
break;
|
break;
|
||||||
case "GeckoView:LoadUri":
|
case "GeckoView:LoadUri":
|
||||||
const { uri, referrer, flags } = aData;
|
const { uri, referrerUri, referrerSessionId, flags } = aData;
|
||||||
|
|
||||||
let navFlags = 0;
|
let navFlags = 0;
|
||||||
|
|
||||||
|
@ -138,10 +138,27 @@ class GeckoViewNavigation extends GeckoViewModule {
|
||||||
this.moduleManager.updateRemoteTypeForURI(uri);
|
this.moduleManager.updateRemoteTypeForURI(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
let parsedUri;
|
let triggeringPrincipal, referrerInfo, csp;
|
||||||
let triggeringPrincipal;
|
if (referrerSessionId) {
|
||||||
|
const referrerWindow = Services.ww.getWindowByName(
|
||||||
|
referrerSessionId,
|
||||||
|
this.window
|
||||||
|
);
|
||||||
|
triggeringPrincipal = referrerWindow.browser.contentPrincipal;
|
||||||
|
csp = referrerWindow.browser.csp;
|
||||||
|
|
||||||
|
const referrerPolicy = referrerWindow.browser.referrerInfo
|
||||||
|
? referrerWindow.browser.referrerInfo.referrerPolicy
|
||||||
|
: Ci.nsIHttpChannel.REFERRER_POLICY_UNSET;
|
||||||
|
|
||||||
|
referrerInfo = new ReferrerInfo(
|
||||||
|
referrerPolicy,
|
||||||
|
true,
|
||||||
|
referrerWindow.browser.documentURI
|
||||||
|
);
|
||||||
|
} else {
|
||||||
try {
|
try {
|
||||||
parsedUri = Services.io.newURI(uri);
|
const parsedUri = Services.io.newURI(uri);
|
||||||
if (
|
if (
|
||||||
parsedUri.schemeIs("about") ||
|
parsedUri.schemeIs("about") ||
|
||||||
parsedUri.schemeIs("data") ||
|
parsedUri.schemeIs("data") ||
|
||||||
|
@ -156,16 +173,37 @@ class GeckoViewNavigation extends GeckoViewModule {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (ignored) {}
|
} catch (ignored) {}
|
||||||
|
|
||||||
|
referrerInfo = createReferrerInfo(referrerUri);
|
||||||
|
}
|
||||||
|
|
||||||
if (!triggeringPrincipal) {
|
if (!triggeringPrincipal) {
|
||||||
triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal(
|
triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.browser.loadURI(parsedUri ? parsedUri.spec : uri, {
|
// For any navigation here, we should have an appropriate triggeringPrincipal:
|
||||||
|
//
|
||||||
|
// 1) If we have a referring session, triggeringPrincipal is the contentPrincipal from the
|
||||||
|
// referring document.
|
||||||
|
// 2) For certain URI schemes listed above, we will have a codebase principal.
|
||||||
|
// 3) In all other cases, we create a NullPrincipal.
|
||||||
|
//
|
||||||
|
// The navigation flags are driven by the app. We purposely do not propagate these from
|
||||||
|
// the referring document, but expect that the app will in most cases.
|
||||||
|
//
|
||||||
|
// The referrerInfo is derived from the referring document, if present, by propagating any
|
||||||
|
// referrer policy. If we only have the referrerUri from the app, we create a referrerInfo
|
||||||
|
// with the specified URI and no policy set. If no referrerUri is present and we have no
|
||||||
|
// referring session, the referrerInfo is null.
|
||||||
|
//
|
||||||
|
// csp is only present if we have a referring document, null otherwise.
|
||||||
|
this.browser.loadURI(uri, {
|
||||||
flags: navFlags,
|
flags: navFlags,
|
||||||
referrerInfo: createReferrerInfo(referrer),
|
referrerInfo,
|
||||||
triggeringPrincipal,
|
triggeringPrincipal,
|
||||||
|
csp,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "GeckoView:Reload":
|
case "GeckoView:Reload":
|
||||||
|
|
Загрузка…
Ссылка в новой задаче