Bug 1591533 - Add GV API to enable DNS-over-HTTPS capability on Fenix r=geckoview-reviewers,calu,owlish

This PR adds a couple GeckoView API to setup and specific DoH TRR mode
and server URI, which enables the DNS-over-HTTPS capability on Firefox
Fenix.

Differential Revision: https://phabricator.services.mozilla.com/D121455
This commit is contained in:
cschanaj 2023-09-14 07:00:52 +00:00
parent b7981e2a45
commit d00a7afc2e
5 changed files with 318 additions and 1 deletions

View File

@ -846,6 +846,7 @@ package org.mozilla.geckoview {
method public int getGlMsaaLevel();
method public boolean getInputAutoZoomEnabled();
method public boolean getJavaScriptEnabled();
method @NonNull public int getLargeKeepaliveFactor();
method @Nullable public String[] getLocales();
method public boolean getLoginAutofillEnabled();
method public boolean getPauseForDebuggerEnabled();
@ -854,6 +855,8 @@ package org.mozilla.geckoview {
method @Nullable public GeckoRuntime getRuntime();
method @Nullable public Rect getScreenSizeOverride();
method @Nullable public RuntimeTelemetry.Delegate getTelemetryDelegate();
method @NonNull public String getTrustedRecursiveResolverUri();
method public int getTrustedRecusiveResolverMode();
method public boolean getUseMaxScreenDepth();
method public boolean getWebFontsEnabled();
method public boolean getWebManifestEnabled();
@ -872,10 +875,13 @@ package org.mozilla.geckoview {
method @NonNull public GeckoRuntimeSettings setGlMsaaLevel(int);
method @NonNull public GeckoRuntimeSettings setInputAutoZoomEnabled(boolean);
method @NonNull public GeckoRuntimeSettings setJavaScriptEnabled(boolean);
method @NonNull public GeckoRuntimeSettings setLargeKeepaliveFactor(int);
method public void setLocales(@Nullable String[]);
method @NonNull public GeckoRuntimeSettings setLoginAutofillEnabled(boolean);
method @NonNull public GeckoRuntimeSettings setPreferredColorScheme(int);
method @NonNull public GeckoRuntimeSettings setRemoteDebuggingEnabled(boolean);
method @NonNull public GeckoRuntimeSettings setTrustedRecursiveResolverMode(int);
method @NonNull public GeckoRuntimeSettings setTrustedRecursiveResolverUri(@NonNull String);
method @NonNull public GeckoRuntimeSettings setWebFontsEnabled(boolean);
method @NonNull public GeckoRuntimeSettings setWebManifestEnabled(boolean);
field public static final int ALLOW_ALL = 0;
@ -885,6 +891,10 @@ package org.mozilla.geckoview {
field public static final Parcelable.Creator<GeckoRuntimeSettings> CREATOR;
field public static final int HTTPS_ONLY = 2;
field public static final int HTTPS_ONLY_PRIVATE = 1;
field public static final int TRR_MODE_DISABLED = 5;
field public static final int TRR_MODE_FIRST = 2;
field public static final int TRR_MODE_OFF = 0;
field public static final int TRR_MODE_ONLY = 3;
}
@AnyThread public static final class GeckoRuntimeSettings.Builder extends RuntimeSettings.Builder<GeckoRuntimeSettings> {
@ -912,6 +922,7 @@ package org.mozilla.geckoview {
method @NonNull public GeckoRuntimeSettings.Builder glMsaaLevel(int);
method @NonNull public GeckoRuntimeSettings.Builder inputAutoZoomEnabled(boolean);
method @NonNull public GeckoRuntimeSettings.Builder javaScriptEnabled(boolean);
method @NonNull public GeckoRuntimeSettings.Builder largeKeepaliveFactor(int);
method @NonNull public GeckoRuntimeSettings.Builder locales(@Nullable String[]);
method @NonNull public GeckoRuntimeSettings.Builder loginAutofillEnabled(boolean);
method @NonNull public GeckoRuntimeSettings.Builder pauseForDebugger(boolean);
@ -919,6 +930,8 @@ package org.mozilla.geckoview {
method @NonNull public GeckoRuntimeSettings.Builder remoteDebuggingEnabled(boolean);
method @NonNull public GeckoRuntimeSettings.Builder screenSizeOverride(int, int);
method @NonNull public GeckoRuntimeSettings.Builder telemetryDelegate(@NonNull RuntimeTelemetry.Delegate);
method @NonNull public GeckoRuntimeSettings.Builder trustedRecursiveResolverMode(int);
method @NonNull public GeckoRuntimeSettings.Builder trustedRecursiveResolverUri(@NonNull String);
method @NonNull public GeckoRuntimeSettings.Builder useMaxScreenDepth(boolean);
method @NonNull public GeckoRuntimeSettings.Builder webFontsEnabled(boolean);
method @NonNull public GeckoRuntimeSettings.Builder webManifest(boolean);
@ -931,6 +944,9 @@ package org.mozilla.geckoview {
@Retention(value=RetentionPolicy.SOURCE) public static interface GeckoRuntimeSettings.HttpsOnlyMode {
}
@Retention(value=RetentionPolicy.SOURCE) public static interface GeckoRuntimeSettings.TrustedRecursiveResolverMode {
}
public class GeckoSession {
ctor public GeckoSession();
ctor public GeckoSession(@Nullable GeckoSessionSettings);

View File

@ -8,11 +8,13 @@ import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.platform.app.InstrumentationRegistry
import junit.framework.TestCase.assertTrue
import org.hamcrest.Matchers.* // ktlint-disable no-wildcard-imports
import org.junit.Assume.assumeThat
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.geckoview.BuildConfig
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.GeckoSession.NavigationDelegate
@ -216,6 +218,48 @@ class RuntimeSettingsTest : BaseSessionTest() {
)
}
@Test
fun largeKeepaliveFactor() {
val defaultLargeKeepaliveFactor = 1
val settings = sessionRule.runtime.settings
val largeKeepaliveFactorPref = "network.http.largeKeepaliveFactor"
var prefValue = (sessionRule.getPrefs(largeKeepaliveFactorPref)[0] as Int)
assertThat(
"default LargeKeepaliveFactor should be 1",
prefValue,
`is`(defaultLargeKeepaliveFactor),
)
for (factor in 1..10) {
settings.setLargeKeepaliveFactor(factor)
prefValue = (sessionRule.getPrefs(largeKeepaliveFactorPref)[0] as Int)
assertThat(
"setting LargeKeepaliveFactor to an integer value between 1..10 should work",
prefValue,
`is`(factor),
)
}
/**
* Setting an invalid factor will cause an exception to be throw in debug build.
* otherwise, the factor will be reset to default when an invalid factor is given.
*/
try {
settings.setLargeKeepaliveFactor(128)
prefValue = (sessionRule.getPrefs(largeKeepaliveFactorPref)[0] as Int)
assertThat(
"set LargeKeepaliveFactor to default when input is invalid",
prefValue,
`is`(defaultLargeKeepaliveFactor),
)
} catch (e: Exception) {
if (BuildConfig.DEBUG_BUILD) {
assertTrue("Should have an exception in DEBUG_BUILD", true)
}
}
}
@Test
fun aboutConfig() {
// This is broken in automation because document channel is enabled by default

View File

@ -0,0 +1,86 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
package org.mozilla.geckoview.test
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.hamcrest.Matchers.* // ktlint-disable no-wildcard-imports
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.geckoview.GeckoRuntimeSettings
@RunWith(AndroidJUnit4::class)
@MediumTest
class TrustedRecursiveResolverTest : BaseSessionTest() {
@Test fun trustedRecursiveResolverMode() {
val settings = sessionRule.runtime.settings
val trustedRecursiveResolverModePerf = "network.trr.mode"
var prefValue = (sessionRule.getPrefs(trustedRecursiveResolverModePerf)[0] as Int)
assertThat(
"Initial TRR mode should be TRR_MODE_OFF (0)",
prefValue,
`is`(0),
)
settings.setTrustedRecursiveResolverMode(GeckoRuntimeSettings.TRR_MODE_FIRST)
prefValue = (sessionRule.getPrefs(trustedRecursiveResolverModePerf)[0] as Int)
assertThat(
"Setting TRR mode to TRR_MODE_FIRST (2)",
prefValue,
`is`(2),
)
settings.setTrustedRecursiveResolverMode(GeckoRuntimeSettings.TRR_MODE_ONLY)
prefValue = (sessionRule.getPrefs(trustedRecursiveResolverModePerf)[0] as Int)
assertThat(
"Setting TRR mode to TRR_MODE_ONLY (3)",
prefValue,
`is`(3),
)
settings.setTrustedRecursiveResolverMode(GeckoRuntimeSettings.TRR_MODE_DISABLED)
prefValue = (sessionRule.getPrefs(trustedRecursiveResolverModePerf)[0] as Int)
assertThat(
"Setting TRR mode to TRR_MODE_DISABLED (5)",
prefValue,
`is`(5),
)
settings.setTrustedRecursiveResolverMode(GeckoRuntimeSettings.TRR_MODE_OFF)
prefValue = (sessionRule.getPrefs(trustedRecursiveResolverModePerf)[0] as Int)
assertThat(
"Setting TRR mode to TRR_MODE_OFF (0)",
prefValue,
`is`(0),
)
}
@Test fun trustedRecursiveResolverUrl() {
val settings = sessionRule.runtime.settings
val trustedRecursiveResolverUriPerf = "network.trr.uri"
var prefValue = (sessionRule.getPrefs(trustedRecursiveResolverUriPerf)[0] as String)
assertThat(
"Initial TRR Uri should be empty",
prefValue,
`is`(""),
)
val exampleValue = "https://mozilla.cloudflare-dns.com/dns-query"
settings.setTrustedRecursiveResolverUri(exampleValue)
prefValue = (sessionRule.getPrefs(trustedRecursiveResolverUriPerf)[0] as String)
assertThat(
"Setting custom TRR Uri should work",
prefValue,
`is`(exampleValue),
)
}
}

View File

@ -490,6 +490,42 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
getSettings().mExtensionsWebAPIEnabled.set(flag);
return this;
}
/**
* Sets whether and how DNS-over-HTTPS (Trusted Recursive Resolver) is configured.
*
* @param mode One of the {@link GeckoRuntimeSettings#TRR_MODE_OFF TrustedRecursiveResolverMode}
* constants.
* @return This Builder instance.
*/
public @NonNull Builder trustedRecursiveResolverMode(
final @TrustedRecursiveResolverMode int mode) {
getSettings().setTrustedRecursiveResolverMode(mode);
return this;
}
/**
* Set the DNS-over-HTTPS server URI.
*
* @param uri URI of the DNS-over-HTTPS server.
* @return This Builder instance.
*/
public @NonNull Builder trustedRecursiveResolverUri(final @NonNull String uri) {
getSettings().setTrustedRecursiveResolverUri(uri);
return this;
}
/**
* Set the factor by which to increase the keepalive timeout when the NS_HTTP_LARGE_KEEPALIVE
* flag is used for a connection.
*
* @param factor FACTOR by which to increase the keepalive timeout.
* @return This Builder instance.
*/
public @NonNull Builder largeKeepaliveFactor(final int factor) {
getSettings().setLargeKeepaliveFactor(factor);
return this;
}
}
private GeckoRuntime mRuntime;
@ -537,6 +573,11 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
new Pref<Boolean>("dom.security.https_only_mode", false);
/* package */ final Pref<Boolean> mHttpsOnlyPrivateMode =
new Pref<Boolean>("dom.security.https_only_mode_pbm", false);
/* package */ final Pref<Integer> mTrustedRecursiveResolverMode =
new Pref<>("network.trr.mode", 0);
/* package */ final Pref<String> mTrustedRecursiveResolverUri = new Pref<>("network.trr.uri", "");
/* package */ final Pref<Integer> mLargeKeepalivefactor =
new Pref<>("network.http.largeKeepaliveFactor", 1);
/* package */ final Pref<Integer> mProcessCount = new Pref<>("dom.ipc.processCount", 2);
/* package */ final Pref<Boolean> mExtensionsWebAPIEnabled =
new Pref<>("extensions.webapi.enabled", false);
@ -1333,6 +1374,129 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
return this;
}
/** The trusted recursive resolver (TRR) modes. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({TRR_MODE_OFF, TRR_MODE_FIRST, TRR_MODE_ONLY, TRR_MODE_DISABLED})
public @interface TrustedRecursiveResolverMode {}
/** Off (default). Use native DNS resolution by default. */
public static final int TRR_MODE_OFF = 0;
/**
* First. Use TRR first, and only if the name resolve fails use the native resolver as a fallback.
*/
public static final int TRR_MODE_FIRST = 2;
/** Only. Only use TRR, never use the native resolver. */
public static final int TRR_MODE_ONLY = 3;
/**
* Off by choice. This is the same as 0 but marks it as done by choice and not done by default.
*/
public static final int TRR_MODE_DISABLED = 5;
/**
* Get whether and how DNS-over-HTTPS (Trusted Recursive Resolver) is configured.
*
* @return One of the {@link GeckoRuntimeSettings#TRR_MODE_OFF TrustedRecursiveResolverMode}
* constants.
*/
public @TrustedRecursiveResolverMode int getTrustedRecusiveResolverMode() {
final int mode = mTrustedRecursiveResolverMode.get();
switch (mode) {
case 2:
return TRR_MODE_FIRST;
case 3:
return TRR_MODE_ONLY;
case 5:
return TRR_MODE_DISABLED;
default:
case 0:
return TRR_MODE_OFF;
}
}
/**
* Get the factor by which to increase the keepalive timeout when the NS_HTTP_LARGE_KEEPALIVE flag
* is used for a connection.
*
* @return An integer factor.
*/
public @NonNull int getLargeKeepaliveFactor() {
return mLargeKeepalivefactor.get();
}
/**
* Set whether and how DNS-over-HTTPS (Trusted Recursive Resolver) is configured.
*
* @param mode One of the {@link GeckoRuntimeSettings#TRR_MODE_OFF TrustedRecursiveResolverMode}
* constants.
* @return This GeckoRuntimeSettings instance.
*/
public @NonNull GeckoRuntimeSettings setTrustedRecursiveResolverMode(
final @TrustedRecursiveResolverMode int mode) {
switch (mode) {
case TRR_MODE_OFF:
case TRR_MODE_FIRST:
case TRR_MODE_ONLY:
case TRR_MODE_DISABLED:
mTrustedRecursiveResolverMode.commit(mode);
break;
default:
throw new IllegalArgumentException("Invalid setting for setTrustedRecursiveResolverMode");
}
return this;
}
private static final int DEFAULT_LARGE_KEEPALIVE_FACTOR = 1;
private int sanitizeLargeKeepaliveFactor(final int factor) {
if (factor < 1 || factor > 10) {
if (BuildConfig.DEBUG_BUILD) {
throw new IllegalArgumentException(
"largeKeepaliveFactor must be between 1 to 10 inclusive");
} else {
Log.e(LOGTAG, "largeKeepaliveFactor must be between 1 to 10 inclusive");
return DEFAULT_LARGE_KEEPALIVE_FACTOR;
}
}
return factor;
}
/**
* Set the factor by which to increase the keepalive timeout when the NS_HTTP_LARGE_KEEPALIVE flag
* is used for a connection.
*
* @param factor FACTOR by which to increase the keepalive timeout.
* @return This GeckoRuntimeSettings instance.
*/
public @NonNull GeckoRuntimeSettings setLargeKeepaliveFactor(final int factor) {
final int newFactor = sanitizeLargeKeepaliveFactor(factor);
mLargeKeepalivefactor.commit(newFactor);
return this;
}
/**
* Get the DNS-over-HTTPS (DoH) server URI.
*
* @return URI of the DoH server.
*/
public @NonNull String getTrustedRecursiveResolverUri() {
return mTrustedRecursiveResolverUri.get();
}
/**
* Set the DNS-over-HTTPS server URI.
*
* @param uri URI of the DNS-over-HTTPS server.
* @return This GeckoRuntimeSettings instance.
*/
public @NonNull GeckoRuntimeSettings setTrustedRecursiveResolverUri(final @NonNull String uri) {
mTrustedRecursiveResolverUri.commit(uri);
return this;
}
// For internal use only
/* protected */ @NonNull
GeckoRuntimeSettings setProcessCount(final int processCount) {

View File

@ -15,6 +15,13 @@ exclude: true
## v119
- Added `remoteType` to GeckoView child crash intent. ([bug 1851518]({{bugzilla}}1851518))
- Added [`GeckoRuntimeSettings#setTrustedRecursiveResolverMode`][119.1] to enable DNS-over-HTTPS using different resolver modes ([bug 1591533]({{bugzilla}}1591533)).
- Added [`GeckoRuntimeSettings#setTrustedRecursiveResolverUri`][119.2] to specify the DNS-over-HTTPS server to be used if DoH is enabled ([bug 1591533]({{bugzilla}}1591533)).
- Added [`GeckoRuntimeSettings#setLargeKeepaliveFactor`][119.3] to increase the keepalive timeout used for a connection ([bug 1591533]({{bugzilla}}1591533)).
[119.1]: {{javadoc_uri}}/GeckoRuntimeSettings.html#setTrustedRecursiveResolverMode-int-
[119.2]: {{javadoc_uri}}/GeckoRuntimeSettings.html#setTrustedRecursiveResolverUri-java.lang.String-
[119.3]: {{javadoc_uri}}/GeckoRuntimeSettings.html#setLargeKeepaliveFactor-int-
## v118
- Added [`ExperimentDelegate`][118.1] to allow GeckoView to send and retrieve experiment information from an embedder.
@ -1428,4 +1435,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]: ee73ede94d2e7c382fe9e9793c1fecbb01beb18d
[api-version]: 87397d7c25be7722bce85c49c52c3e5ce4e8c420