Bug 1837601 - Indicate if location change was requested by user. r=owlish,amejiamarmol

Differential Revision: https://phabricator.services.mozilla.com/D199568
This commit is contained in:
Roger Yang 2024-02-22 15:36:53 +00:00
parent 584444bde5
commit a3d43670ce
18 changed files with 169 additions and 25 deletions

View file

@ -51,6 +51,7 @@ import java.lang.Boolean;
import java.lang.CharSequence;
import java.lang.Class;
import java.lang.Comparable;
import java.lang.Deprecated;
import java.lang.Double;
import java.lang.Exception;
import java.lang.Float;
@ -85,6 +86,7 @@ import org.mozilla.geckoview.CompositorController;
import org.mozilla.geckoview.ContentBlocking;
import org.mozilla.geckoview.ContentBlockingController;
import org.mozilla.geckoview.CrashHandler;
import org.mozilla.geckoview.DeprecationSchedule;
import org.mozilla.geckoview.ExperimentDelegate;
import org.mozilla.geckoview.GeckoDisplay;
import org.mozilla.geckoview.GeckoResult;
@ -1262,7 +1264,8 @@ package org.mozilla.geckoview {
method @UiThread default public void onCanGoForward(@NonNull GeckoSession, boolean);
method @Nullable @UiThread default public GeckoResult<String> onLoadError(@NonNull GeckoSession, @Nullable String, @NonNull WebRequestError);
method @Nullable @UiThread default public GeckoResult<AllowOrDeny> onLoadRequest(@NonNull GeckoSession, @NonNull GeckoSession.NavigationDelegate.LoadRequest);
method @UiThread default public void onLocationChange(@NonNull GeckoSession, @Nullable String, @NonNull List<GeckoSession.PermissionDelegate.ContentPermission>);
method @Deprecated @DeprecationSchedule(id="geckoview-onlocationchange",version=127) @UiThread default public void onLocationChange(@NonNull GeckoSession, @Nullable String, @NonNull List<GeckoSession.PermissionDelegate.ContentPermission>);
method @UiThread default public void onLocationChange(@NonNull GeckoSession, @Nullable String, @NonNull List<GeckoSession.PermissionDelegate.ContentPermission>, @NonNull Boolean);
method @Nullable @UiThread default public GeckoResult<GeckoSession> onNewSession(@NonNull GeckoSession, @NonNull String);
method @Nullable @UiThread default public GeckoResult<AllowOrDeny> onSubframeLoadRequest(@NonNull GeckoSession, @NonNull GeckoSession.NavigationDelegate.LoadRequest);
field public static final int LOAD_REQUEST_IS_REDIRECT = 8388608;

View file

@ -0,0 +1,10 @@
<html>
<head>
<meta charset="utf-8" />
<title>Hello, world!</title>
<meta name="viewport" content="initial-scale=1.0" />
</head>
<body style="height: 100%" onclick="window.location.replace('replacedUrl')">
<p>Hello, world!</p>
</body>
</html>

View file

@ -36,6 +36,7 @@ open class BaseSessionTest(
const val RESUBMIT_CONFIRM = "/assets/www/resubmit.html"
const val BEFORE_UNLOAD = "/assets/www/beforeunload.html"
const val CLICK_TO_RELOAD_HTML_PATH = "/assets/www/clickToReload.html"
const val CLICK_TO_REPLACE_HTML_PATH = "/assets/www/clickToReplace.html"
const val CLIPBOARD_READ_HTML_PATH = "/assets/www/clipboard_read.html"
const val CONTENT_CRASH_URL = "about:crashcontent"
const val DND_HTML_PATH = "/assets/www/dnd.html"

View file

@ -86,6 +86,7 @@ class GeckoAppShellTest : BaseSessionTest() {
// This is waiting and holding the test harness open while Android Lifecycle events complete
mainSession.waitUntilCalled(object : GeckoSession.ContentDelegate, GeckoSession.NavigationDelegate {
@GeckoSessionTestRule.AssertCalled(count = 2)
@Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,

View file

@ -1115,6 +1115,7 @@ class GeckoSessionTestRuleTest : BaseSessionTest(noErrorCollector = true) {
@NullDelegate(NavigationDelegate::class)
fun delegateDuringNextWait_throwOnNullDelegate() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
}
})

View file

@ -123,6 +123,7 @@ class NavigationDelegateTest : BaseSessionTest() {
if (errorPageUrl != null) {
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
@AssertCalled(count = 1, order = [1])
@Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
@ -593,6 +594,7 @@ class NavigationDelegateTest : BaseSessionTest() {
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
@AssertCalled(count = 1, order = [1])
@Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
@ -646,6 +648,7 @@ class NavigationDelegateTest : BaseSessionTest() {
// No good way to wait for loading about:blank error page. Use onLocaitonChange etc.
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
@Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
@ -1478,10 +1481,12 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("Session should not be null", session, notNullValue())
assertThat("URL should not be null", url, notNullValue())
assertThat("URL should match", url, endsWith(HELLO_HTML_PATH))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1, order = [2])
@ -1514,8 +1519,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URL should match the provided data URL", url, equalTo(dataUrl))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@ -1542,6 +1549,7 @@ class NavigationDelegateTest : BaseSessionTest() {
// Test that if we unset the navigation delegate during a load, the load still proceeds.
var onLocationCount = 0
mainSession.navigationDelegate = object : NavigationDelegate {
@Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,
@ -1587,12 +1595,14 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat(
"URL should be a data URL",
url,
equalTo(createDataUri(dataString, mimeType)),
)
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@ -1612,8 +1622,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URL should be a data URL", url, startsWith("data:"))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@ -1641,8 +1653,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URL should match", url, equalTo(createDataUri(bytes, "text/html")))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@ -1683,8 +1697,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URL should match", url, equalTo(createDataUri(bytes, mimeType)))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1)
@ -1740,8 +1756,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URL should match", url, endsWith(HELLO_HTML_PATH))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1, order = [2])
@ -1774,8 +1792,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URL should match", url, endsWith(HELLO2_HTML_PATH))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
})
@ -1802,8 +1822,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URL should match", url, endsWith(HELLO_HTML_PATH))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1, order = [2])
@ -1845,8 +1867,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URL should match", url, endsWith(HELLO2_HTML_PATH))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
@AssertCalled(count = 1, order = [2])
@ -2621,6 +2645,7 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
currentUrl = url
}
@ -2717,8 +2742,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URI should match", url, endsWith("#test1"))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
})
@ -2739,8 +2766,10 @@ class NavigationDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URI should match", url, endsWith("#test2"))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
})
}
@ -2830,6 +2859,54 @@ class NavigationDelegateTest : BaseSessionTest() {
})
}
@WithDisplay(width = 100, height = 100)
@Test
fun locationReplaceOnUserGesture() {
mainSession.loadUri("$TEST_ENDPOINT$CLICK_TO_REPLACE_HTML_PATH")
mainSession.waitForPageStop()
mainSession.synthesizeTap(50, 50)
sessionRule.waitUntilCalled(object : NavigationDelegate {
@AssertCalled(count = 1)
override fun onLocationChange(
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("Should have a user gesture", hasUserGesture, equalTo(true))
assertThat(
"Location should be replaced to replacedUrl",
url,
equalTo("replacedUrl"),
)
}
})
}
@WithDisplay(width = 100, height = 100)
@Test
fun locationNotReplaceOnNoUserGesture() {
mainSession.loadUri("$TEST_ENDPOINT$HELLO_HTML_PATH")
sessionRule.waitForPageStop()
sessionRule.forCallbacksDuringWait(object : NavigationDelegate {
@AssertCalled(count = 1, order = [2])
override fun onLocationChange(
session: GeckoSession,
url: String?,
perms: MutableList<PermissionDelegate.ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("Session should not be null", session, notNullValue())
assertThat("URL should not be null", url, notNullValue())
assertThat("URL should match", url, endsWith(HELLO_HTML_PATH))
assertThat("Should not have user gesture", hasUserGesture, equalTo(false))
}
})
}
@Test fun loadAfterLoad() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 2)
@ -3119,6 +3196,7 @@ class NavigationDelegateTest : BaseSessionTest() {
var lastTitle: String? = ""
sessionRule.delegateDuringNextWait(object : NavigationDelegate, ContentDelegate {
@AssertCalled(count = 1)
@Suppress("OVERRIDE_DEPRECATION")
override fun onLocationChange(
session: GeckoSession,
url: String?,

View file

@ -64,7 +64,7 @@ class OpenWindowTest : BaseSessionTest() {
@NullDelegate(ServiceWorkerDelegate::class)
fun openWindowNullDelegate() {
sessionRule.delegateUntilTestEnd(object : ContentDelegate, NavigationDelegate {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
// we should not open the target url
assertThat("URL should notmatch", url, not(createTestUrl(OPEN_WINDOW_TARGET_PATH)))
}
@ -76,7 +76,7 @@ class OpenWindowTest : BaseSessionTest() {
@Test
fun openWindowNullResult() {
sessionRule.delegateUntilTestEnd(object : ContentDelegate, NavigationDelegate {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
// we should not open the target url
assertThat("URL should notmatch", url, not(createTestUrl(OPEN_WINDOW_TARGET_PATH)))
}
@ -103,7 +103,7 @@ class OpenWindowTest : BaseSessionTest() {
openPageClickNotification()
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
@AssertCalled(count = 1, order = [1])
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
assertThat("Should be on the main session", session, equalTo(mainSession))
assertThat("URL should match", url, equalTo(createTestUrl(OPEN_WINDOW_TARGET_PATH)))
}
@ -130,7 +130,7 @@ class OpenWindowTest : BaseSessionTest() {
openPageClickNotification()
sessionRule.waitUntilCalled(object : ContentDelegate, NavigationDelegate {
@AssertCalled(count = 1, order = [1])
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
assertThat("Should be on the target session", session, equalTo(targetSession))
assertThat("URL should match", url, equalTo(createTestUrl(OPEN_WINDOW_TARGET_PATH)))
}

View file

@ -275,7 +275,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_GEOLOCATION &&
@ -342,7 +342,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_GEOLOCATION &&
@ -462,6 +462,7 @@ class PermissionDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<ContentPermission>,
hasUserGesture: Boolean,
) {
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_TRACKING) {
@ -501,6 +502,7 @@ class PermissionDelegateTest : BaseSessionTest() {
assertTrackingProtectionPermission(null)
mainSession.loadTestPath(HELLO_HTML_PATH)
mainSession.waitForPageStop()
assertTrackingProtectionPermission(ContentPermission.VALUE_DENY)
}
@ -551,7 +553,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@ -617,7 +619,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@ -707,7 +709,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@ -777,7 +779,7 @@ class PermissionDelegateTest : BaseSessionTest() {
session2.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@ -841,7 +843,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&
@ -919,7 +921,7 @@ class PermissionDelegateTest : BaseSessionTest() {
mainSession.delegateDuringNextWait(object : NavigationDelegate {
@AssertCalled(count = 1)
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
var permFound2 = false
for (perm in perms) {
if (perm.permission == PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION &&

View file

@ -33,7 +33,7 @@ class ProgressDelegateTest : BaseSessionTest() {
ProgressDelegate,
NavigationDelegate {
@AssertCalled
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
assertThat("LocationChange is called", url, endsWith(path))
}
@ -467,6 +467,7 @@ class ProgressDelegateTest : BaseSessionTest() {
session: GeckoSession,
url: String?,
perms: MutableList<ContentPermission>,
hasUserGesture: Boolean,
) {
assertThat("URI should match", url, equalTo(startUri))
}
@ -487,7 +488,7 @@ class ProgressDelegateTest : BaseSessionTest() {
session.goBack()
session.waitUntilCalled(object : NavigationDelegate {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
assertThat("History should be preserved", url, equalTo(helloUri))
}
})
@ -511,7 +512,7 @@ class ProgressDelegateTest : BaseSessionTest() {
sessionRule.forCallbacksDuringWait(object : NavigationDelegate {
@AssertCalled
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<ContentPermission>, hasUserGesture: Boolean) {
assertThat("URI should match", url, equalTo(startUri))
}
})

View file

@ -36,7 +36,8 @@ public class TrackingPermissionService extends TestRuntimeService {
public void onLocationChange(
final @NonNull GeckoSession session,
final @Nullable String url,
final @NonNull List<ContentPermission> perms) {
final @NonNull List<ContentPermission> perms,
final @NonNull Boolean hasUserGesture) {
for (ContentPermission perm : perms) {
if (perm.permission == PermissionDelegate.PERMISSION_TRACKING) {
mContentPermission = perm;

View file

@ -2138,7 +2138,7 @@ class WebExtensionTest : BaseSessionTest() {
mainSession.waitUntilCalled(object : NavigationDelegate, ProgressDelegate {
@GeckoSessionTestRule.AssertCalled(count = 1)
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
assertThat(
"Url should load example.com first",
url,
@ -2160,7 +2160,7 @@ class WebExtensionTest : BaseSessionTest() {
val pageStop = GeckoResult<Boolean>()
mainSession.delegateUntilTestEnd(object : NavigationDelegate, ProgressDelegate {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>) {
override fun onLocationChange(session: GeckoSession, url: String?, perms: MutableList<PermissionDelegate.ContentPermission>, hasUserGesture: Boolean) {
page = url
}

View file

@ -831,7 +831,8 @@ public class GeckoSessionTestRule implements TestRule {
public void onLocationChange(
@NonNull GeckoSession session,
@Nullable String url,
@NonNull List<ContentPermission> perms) {}
@NonNull List<ContentPermission> perms,
@NonNull Boolean hasUserGesture) {}
@Override
public void onShutdown() {}

View file

@ -685,7 +685,11 @@ public class GeckoSession {
final GeckoBundle[] perms = message.getBundleArray("permissions");
final List<PermissionDelegate.ContentPermission> permList =
PermissionDelegate.ContentPermission.fromBundleArray(perms);
delegate.onLocationChange(GeckoSession.this, message.getString("uri"), permList);
delegate.onLocationChange(
GeckoSession.this,
message.getString("uri"),
permList,
message.getBoolean("hasUserGesture"));
}
delegate.onCanGoBack(GeckoSession.this, message.getBoolean("canGoBack"));
delegate.onCanGoForward(GeckoSession.this, message.getBoolean("canGoForward"));
@ -4935,16 +4939,38 @@ public class GeckoSession {
/**
* A view has started loading content from the network.
*
* @deprecated use {@link #onLocationChange(GeckoSession, String,
* List<PermissionDelegate.ContentPermission>, Boolean) onLocationChange} instead
* @param session The GeckoSession that initiated the callback.
* @param url The resource being loaded.
* @param perms The permissions currently associated with this url.
*/
@UiThread
@Deprecated
@DeprecationSchedule(id = "geckoview-onlocationchange", version = 127)
default void onLocationChange(
@NonNull GeckoSession session,
@Nullable String url,
final @NonNull List<PermissionDelegate.ContentPermission> perms) {}
/**
* A view has started loading content from the network.
*
* @param session The GeckoSession that initiated the callback.
* @param url The resource being loaded.
* @param perms The permissions currently associated with this url.
* @param hasUserGesture Whether or not there was an active user gesture when the location
* change was requested.
*/
@UiThread
default void onLocationChange(
@NonNull GeckoSession session,
@Nullable String url,
final @NonNull List<PermissionDelegate.ContentPermission> perms,
final @NonNull Boolean hasUserGesture) {
session.getNavigationDelegate().onLocationChange(session, url, perms);
}
/**
* The view's ability to go back has changed.
*

View file

@ -13,6 +13,16 @@ exclude: true
⚠️ breaking change and deprecation notices
## v125
- ⚠️ Deprecated [`GeckoSession.NavigationDelegate.onLocationChange`][125.1], to be removed in v127.
([bug 1837601]({{bugzilla}}1837601))
- Added [`GeckoSession.NavigationDelegate.onLocationChange#hasUserGesture`][125.2]. This indicates if a location change was requested
while a user gesture was active (e.g., a tap).
([bug 1837601]({{bugzilla}}1837601))
[125.1]: {{javadoc_uri}}/GeckoSession.NavigationDelegate#onLocationChange(org.mozilla.geckoview.GeckoSession,java.lang.String,java.util.List)
[125.2]: {{javadoc_uri}}/GeckoSession.NavigationDelegate#onLocationChange(org.mozilla.geckoview.GeckoSession,java.lang.String,java.util.List,boolean)
## v124
- Added [`GeckoRuntimeSettings#setTrustedRecursiveResolverMode`][124.1] to enable DNS-over-HTTPS using different resolver modes ([bug 1591533]({{bugzilla}}1591533)).
@ -36,7 +46,7 @@ exclude: true
[123.1]: {{javadoc_uri}}/TranslationsController.RuntimeTranslation.html#checkPairDownloadSize(java.lang.String,java.lang.String)
[123.2]: {{javadoc_uri}}/TranslationsController.TranslationsException.html#ERROR_MODEL_LANGUAGE_REQUIRED
[121.3]: {{javadoc_uri}}/GeckoSession.html#sendPlacementAttributionEvent(String)
[123.3]: {{javadoc_uri}}/GeckoSession.html#sendPlacementAttributionEvent(String)
## v122
- ⚠️ Removed [`onGetNimbusFeature`][115.5], please use `ExperimentDelegate.onGetExperimentFeature` instead.
@ -1519,4 +1529,4 @@ to allow adding gecko profiler markers.
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport(android.content.Context,android.os.Bundle,java.lang.String)
[65.25]: {{javadoc_uri}}/GeckoResult.html
[api-version]: ff5a513251f19534bbf4ebe0084909665d00a227
[api-version]: f3786e0fcd543773be728be1ff2bf27ac23566d5

View file

@ -2624,7 +2624,10 @@ public class GeckoViewActivity extends AppCompatActivity
private class ExampleNavigationDelegate implements GeckoSession.NavigationDelegate {
@Override
public void onLocationChange(
GeckoSession session, final String url, final List<ContentPermission> perms) {
GeckoSession session,
final String url,
final List<ContentPermission> perms,
Boolean hasUserGesture) {
mToolbarView.getLocationView().setText(url);
TabSession tabSession = mTabSessionManager.getSession(session);
if (tabSession != null) {

View file

@ -648,6 +648,8 @@ export class GeckoViewNavigation extends GeckoViewModule {
canGoForward: this.browser.canGoForward,
isTopLevel: aWebProgress.isTopLevel,
permissions,
hasUserGesture:
this.window.document.hasValidTransientUserGestureActivation,
};
lazy.TranslationsParent.onLocationChange(this.browser);
this.eventDispatcher.sendRequest(message);

View file

@ -608,6 +608,7 @@ export class GeckoViewProgress extends GeckoViewModule {
canGoBack: false,
canGoForward: false,
isTopLevel: true,
hasUserGesture: false,
});
this.eventDispatcher.sendRequest({
type: "GeckoView:PageStop",

View file

@ -163,7 +163,10 @@ public class TestRunnerActivity extends Activity {
new GeckoSession.NavigationDelegate() {
@Override
public void onLocationChange(
final GeckoSession session, final String url, final List<ContentPermission> perms) {
final GeckoSession session,
final String url,
final List<ContentPermission> perms,
final Boolean hasUserGesture) {
getActionBar().setSubtitle(url);
}