commit b6bd3b692663cf067f0c8f40b813036c374e3452
parent 07cb846c4f7b5c342fb45318b958f4e441912a8d
Author: Segun Famisa <sfamisa@mozilla.com>
Date: Fri, 21 Nov 2025 14:22:31 +0000
Bug 1989004 - Add more granular LNA Gecko API & prefs r=geckoview-reviewers,geckoview-api-reviewers,ohall,owlish
This patch introduces more specific APIs for controlling the Local Network Access (LNA) feature in `GeckoRuntimeSettings` and its `Builder`.
The single `setLnaBlockingEnabled` API has been deprecated and replaced with three new, more granular controls:
- `setLnaEnabled`: Toggles the entire LNA feature on or off.
- `setLnaBlockTrackers`: Controls whether the tracker blocking feature of LNA is enabled.
- `setLnaBlocking`: Manages the request blocking aspects of LNA blocking.
Changes:
- Deprecated `getLnaBlockingEnabled` and `setLnaBlockingEnabled` in `GeckoRuntimeSettings` and its `Builder`.
- Added new methods: `get/setLnaEnabled`, `get/setLnaBlockTrackers`, and `get/setLnaEnabled` to `GeckoRuntimeSettings`.
- Added corresponding setters to `GeckoRuntimeSettings.Builder`.
- Renamed the preference `mLnaBlockingEnabled` to `mLnaBlocking` and added new preferences `mLnaEnabled` and `mLnaBlockTrackers` to align with the new APIs.
- Updated `LocalNetworkAccessTest` to cover the new, more specific APIs.
- Updated `CHANGELOG.md` to document the API changes.
Differential Revision: https://phabricator.services.mozilla.com/D272454
Diffstat:
5 files changed, 306 insertions(+), 23 deletions(-)
diff --git a/mobile/android/geckoview/api.txt b/mobile/android/geckoview/api.txt
@@ -53,6 +53,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;
@@ -90,6 +91,7 @@ import org.mozilla.geckoview.ContentBlocking;
import org.mozilla.geckoview.ContentBlockingController;
import org.mozilla.geckoview.CrashHandler;
import org.mozilla.geckoview.CrashPullController;
+import org.mozilla.geckoview.DeprecationSchedule;
import org.mozilla.geckoview.ExperimentDelegate;
import org.mozilla.geckoview.GeckoDisplay;
import org.mozilla.geckoview.GeckoPreferenceController;
@@ -1038,7 +1040,10 @@ package org.mozilla.geckoview {
method public boolean getIsolatedProcessEnabled();
method public boolean getJavaScriptEnabled();
method @NonNull public int getLargeKeepaliveFactor();
- method public boolean getLnaBlockingEnabled();
+ method @Nullable public Boolean getLnaBlockTrackers();
+ method @Nullable public Boolean getLnaBlocking();
+ method @Deprecated @DeprecationSchedule(id="deprecated-lna-api",version=148) public boolean getLnaBlockingEnabled();
+ method @Nullable public Boolean getLnaEnabled();
method @Nullable public String[] getLocales();
method public boolean getLoginAutofillEnabled();
method public boolean getLowMemoryDetection();
@@ -1093,7 +1098,10 @@ package org.mozilla.geckoview {
method @NonNull public GeckoRuntimeSettings setInputAutoZoomEnabled(boolean);
method @NonNull public GeckoRuntimeSettings setJavaScriptEnabled(boolean);
method @NonNull public GeckoRuntimeSettings setLargeKeepaliveFactor(int);
- method @NonNull public GeckoRuntimeSettings setLnaBlockingEnabled(boolean);
+ method @NonNull public GeckoRuntimeSettings setLnaBlockTrackers(boolean);
+ method @NonNull public GeckoRuntimeSettings setLnaBlocking(boolean);
+ method @Deprecated @DeprecationSchedule(id="deprecated-lna-api",version=148) @NonNull public GeckoRuntimeSettings setLnaBlockingEnabled(boolean);
+ method @NonNull public GeckoRuntimeSettings setLnaEnabled(boolean);
method public void setLocales(@Nullable String[]);
method @NonNull public GeckoRuntimeSettings setLoginAutofillEnabled(boolean);
method @NonNull public GeckoRuntimeSettings setParallelMarkingEnabled(boolean);
@@ -1169,7 +1177,10 @@ package org.mozilla.geckoview {
method @NonNull public GeckoRuntimeSettings.Builder preferredColorScheme(int);
method @NonNull public GeckoRuntimeSettings.Builder remoteDebuggingEnabled(boolean);
method @NonNull public GeckoRuntimeSettings.Builder screenSizeOverride(int, int);
- method @NonNull public GeckoRuntimeSettings.Builder setLnaBlockingEnabled(@NonNull Boolean);
+ method @NonNull public GeckoRuntimeSettings.Builder setLnaBlockTrackers(@NonNull Boolean);
+ method @NonNull public GeckoRuntimeSettings.Builder setLnaBlocking(@NonNull Boolean);
+ method @Deprecated @DeprecationSchedule(id="deprecated-lna-api",version=148) @NonNull public GeckoRuntimeSettings.Builder setLnaBlockingEnabled(@NonNull Boolean);
+ method @NonNull public GeckoRuntimeSettings.Builder setLnaEnabled(@NonNull Boolean);
method @NonNull public GeckoRuntimeSettings.Builder setSameDocumentNavigationOverridesLoadType(boolean);
method @NonNull public GeckoRuntimeSettings.Builder setSameDocumentNavigationOverridesLoadTypeForceDisable(@NonNull String);
method @NonNull public GeckoRuntimeSettings.Builder translationsOfferPopup(boolean);
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/LocalNetworkAccessTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/LocalNetworkAccessTest.kt
@@ -10,58 +10,171 @@ import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
+/**
+ * This pref references the request blocking feature of the Local Network / Device Access feature.
+ */
private const val LNA_BLOCKING_PREF = "network.lna.blocking"
+/**
+ * This pref references the tracker blocking features of the Local Network / Device Access feature.
+ */
+private const val LNA_TRACKER_BLOCKING_PREF = "network.lna.block_trackers"
+
+/**
+ * This pref references the state of the overall Local Network / Device Access feature.
+ */
+private const val LNA_FEATURE_ENABLED_PREF = "network.lna.enabled"
+
@RunWith(AndroidJUnit4::class)
class LocalNetworkAccessTest : BaseSessionTest() {
@Test
- fun setLnaBlockingEnabled_updatesPrefsToTrue() {
+ fun setLnaBlocking_updatesPrefsToTrue() {
val settings = sessionRule.runtime.settings
- settings.setLnaBlockingEnabled(true)
+ settings.setLnaBlocking(true)
val lnaBlockingPrefValue = sessionRule.getPrefs(LNA_BLOCKING_PREF)[0] as Boolean
assertTrue(
- "Calling setLnaBLockingEnabled(true) should set the pref to true",
+ "Calling setLnaBlocking(true) should set the pref to true",
lnaBlockingPrefValue,
)
}
@Test
- fun setLnaBlockingEnabled_updatesPrefsToFalse() {
+ fun setLnaBlocking_updatesPrefsToFalse() {
val settings = sessionRule.runtime.settings
- settings.setLnaBlockingEnabled(false)
+ settings.setLnaBlocking(false)
val lnaBlockingPrefValue = sessionRule.getPrefs(LNA_BLOCKING_PREF)[0] as Boolean
assertFalse(
- "Calling setLnaBLockingEnabled(false) should set the pref to false",
+ "Calling setLnaBlocking(false) should set the pref to false",
lnaBlockingPrefValue,
)
}
@Test
- fun getLnaBlockingEnabled_returnsTrueWhenLnaBlockingIsSetToTrue() {
+ fun setLnaBlocking_returnsTrueWhenLnaBlockingIsSetToTrue() {
+ val settings = sessionRule.runtime.settings
+ settings.setLnaBlocking(true)
+
+ assertTrue(
+ "setLnaBlocking() should return true",
+ settings.lnaBlocking!!,
+ )
+ }
+
+ @Test
+ fun setLnaBlocking_returnsFalseWhenLnaBlockingIsSetToFalse() {
+ val settings = sessionRule.runtime.settings
+ settings.setLnaBlocking(false)
+
+ assertFalse(
+ "setLnaBlocking() should return false",
+ settings.lnaBlocking!!,
+ )
+ }
+
+ @Test
+ fun getLnaFeatureEnabled_returnsTrueWhenLnaFeatureIsSetToTrue() {
+ val settings = sessionRule.runtime.settings
+ settings.setLnaEnabled(true)
+
+ assertTrue(
+ "getLnaFeatureEnabled() should return true",
+ settings.lnaEnabled!!,
+ )
+ }
+
+ @Test
+ fun getLnaFeatureEnabled_returnsFalseWhenLnaFeatureIsSetToFalse() {
+ val settings = sessionRule.runtime.settings
+ settings.setLnaEnabled(false)
+
+ assertFalse(
+ "getLnaFeatureEnabled() should return false",
+ settings.lnaEnabled!!,
+ )
+ }
+
+ @Test
+ fun setLnaFeatureEnabled_updatesPrefsToTrue() {
+ val settings = sessionRule.runtime.settings
+ settings.setLnaEnabled(true)
+
+ val lnaFeatureEnabledPrefValue =
+ sessionRule.getPrefs(LNA_FEATURE_ENABLED_PREF)[0] as Boolean
+ assertTrue(
+ "Calling setLnaFeatureEnabled(true) should set the pref to true",
+ lnaFeatureEnabledPrefValue,
+ )
+ }
+
+ @Test
+ fun setLnaEnabled_updatesPrefsToFalse() {
+ val settings = sessionRule.runtime.settings
+ settings.setLnaEnabled(false)
+
+ val lnaEnabledPrefValue =
+ sessionRule.getPrefs(LNA_FEATURE_ENABLED_PREF)[0] as Boolean
+ assertFalse(
+ "Calling setLnaEnabled(false) should set the pref to false",
+ lnaEnabledPrefValue,
+ )
+ }
+
+ @Test
+ fun getLnaBlockTrackers_returnsFalseWhenLnaTrackerBlockingIsSetToFalse() {
val settings = sessionRule.runtime.settings
- settings.setLnaBlockingEnabled(true)
+ settings.setLnaBlockTrackers(false)
+
+ assertFalse(
+ "getLnaBlockTrackers() should return false",
+ settings.lnaBlockTrackers!!,
+ )
+ }
+
+ @Test
+ fun getLnaBlockTrackers_returnsTrueWhenLnaTrackerBlockingIsSetToTrue() {
+ val settings = sessionRule.runtime.settings
+ settings.setLnaBlockTrackers(true)
assertTrue(
- "getLnaBlockingEnabled() should return true",
- settings.lnaBlockingEnabled,
+ "getLnaBlockTrackers() should return true",
+ settings.lnaBlockTrackers!!,
)
}
@Test
- fun getLnaBlockingEnabled_returnsFalseWhenLnaBlockingIsSetToFalse() {
+ fun setLnaBlockTrackers_updatesPrefsToTrue() {
val settings = sessionRule.runtime.settings
- settings.setLnaBlockingEnabled(false)
+
+ settings.setLnaBlockTrackers(true)
+
+ val lnaTrackerBlockingPrefValue =
+ sessionRule.getPrefs(LNA_TRACKER_BLOCKING_PREF)[0] as Boolean
+
+ assertTrue(
+ "Calling setLnaBlockTrackers(true) should set the pref to true",
+ lnaTrackerBlockingPrefValue,
+ )
+ }
+
+ @Test
+ fun setLnaBlockTrackers_updatesPrefsToFalse() {
+ val settings = sessionRule.runtime.settings
+
+ settings.setLnaBlockTrackers(false)
+
+ val lnaTrackerBlockingPrefValue =
+ sessionRule.getPrefs(LNA_TRACKER_BLOCKING_PREF)[0] as Boolean
assertFalse(
- "getLnaBlockingEnabled() should return false",
- settings.lnaBlockingEnabled,
+ "Calling setLnaBlockTrackers(false) should set the pref to false",
+ lnaTrackerBlockingPrefValue,
)
}
}
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PermissionDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PermissionDelegateTest.kt
@@ -1204,7 +1204,14 @@ class PermissionDelegateTest : BaseSessionTest() {
@Test
fun localDeviceAccessPermission() {
- sessionRule.setPrefsUntilTestEnd(mapOf("network.lna.blocking" to true))
+ sessionRule.setPrefsUntilTestEnd(
+ mapOf(
+ "network.lna.blocking" to true,
+ "network.lna.enabled" to true,
+ "network.lna.block_trackers" to true,
+ ),
+ )
+
// enable LNA checks for local network to localhost checks
sessionRule.setPrefsUntilTestEnd(mapOf("network.lna.local-network-to-localhost.skip-checks" to false))
@@ -1247,7 +1254,13 @@ class PermissionDelegateTest : BaseSessionTest() {
@Test
fun localDeviceAccessPermissionNotFiredIfPrefIsFalse() {
- sessionRule.setPrefsUntilTestEnd(mapOf("network.lna.blocking" to false))
+ sessionRule.setPrefsUntilTestEnd(
+ mapOf(
+ "network.lna.blocking" to false,
+ "network.lna.enabled" to false,
+ "network.lna.block_trackers" to false,
+ ),
+ )
mainSession.loadUri("https://example.com/")
mainSession.waitForPageStop()
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
@@ -572,15 +572,58 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
/**
* Sets whether or not local network access (LNA) blocking is enabled
*
+ * @deprecated This API is deprecated and may not work as expected. Please use {@link
+ * #setLnaEnabled(Boolean)}, {@link #setLnaBlocking(Boolean)} and {@link
+ * #setLnaBlockTrackers(Boolean)}} for more fine-grained control.
* @param enabled flag indicating whether or not local network access (LNA) blocking is enabled
* @return The builder instance
*/
+ @Deprecated
+ @DeprecationSchedule(id = "deprecated-lna-api", version = 148)
public @NonNull Builder setLnaBlockingEnabled(@NonNull final Boolean enabled) {
getSettings().setLnaBlockingEnabled(enabled);
return this;
}
/**
+ * Sets whether or not the request blocking feature for Local Network / Device Access blocking
+ * is enabled
+ *
+ * @param enabled flag indicating whether or not the request blocking feature for Local Network
+ * / Device Access blocking is enabled
+ * @return The builder instance
+ */
+ public @NonNull Builder setLnaBlocking(@NonNull final Boolean enabled) {
+ getSettings().setLnaBlocking(enabled);
+ return this;
+ }
+
+ /**
+ * Sets whether or not the tracker blocking feature on Local Network / Device Access blocking
+ * feature is enabled
+ *
+ * @param enabled flag indicating whether or not the tracker blocking feature for Local Network
+ * / Device Access blocking is enabled
+ * @return The builder instance
+ */
+ public @NonNull Builder setLnaBlockTrackers(@NonNull final Boolean enabled) {
+ getSettings().setLnaBlockTrackers(enabled);
+ return this;
+ }
+
+ /**
+ * Sets whether or not the overall Local Network / Device Access blocking feature is enabled
+ *
+ * @param enabled flag indicating whether or not the overall Local Network / Device Access
+ * blocking feature is enabled
+ * @return The builder instance
+ */
+ public @NonNull Builder setLnaEnabled(@NonNull final Boolean enabled) {
+ getSettings().setLnaEnabled(enabled);
+ 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}
@@ -755,7 +798,12 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
/* package */ final Pref<Boolean> mHttpsOnlyPrivateMode =
new Pref<Boolean>("dom.security.https_only_mode_pbm", false);
- /* package */ final Pref<Boolean> mLnaBlockingEnabled = new Pref<>("network.lna.blocking", false);
+ /* package */ final PrefWithoutDefault<Boolean> mLnaBlocking =
+ new PrefWithoutDefault<>("network.lna.blocking");
+ /* package */ final PrefWithoutDefault<Boolean> mLnaBlockTrackers =
+ new PrefWithoutDefault<>("network.lna.block_trackers");
+ /* package */ final PrefWithoutDefault<Boolean> mLnaEnabled =
+ new PrefWithoutDefault<>("network.lna.enabled");
/* package */ final PrefWithoutDefault<Integer> mTrustedRecursiveResolverMode =
new PrefWithoutDefault<>("network.trr.mode");
/* package */ final PrefWithoutDefault<String> mTrustedRecursiveResolverUri =
@@ -1997,6 +2045,72 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
return this;
}
+ /**
+ * Sets whether or not the request blocking feature of Local Network / Device Access is enabled
+ *
+ * @param enabled flag indicating whether or not the request blocking feature of Local Network /
+ * Device Access is enabled
+ * @return The updated instance of {@link GeckoRuntimeSettings}
+ */
+ public @NonNull GeckoRuntimeSettings setLnaBlocking(final boolean enabled) {
+ mLnaBlocking.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Gets whether or not the request blocking feature for Local Network / Device Access is enabled
+ *
+ * @return Boolean indicating whether or not the request blocking feature of Local Network /
+ * Device Access blocking is enabled or not.
+ */
+ public @Nullable Boolean getLnaBlocking() {
+ return mLnaBlocking.get();
+ }
+
+ /**
+ * Sets whether or not the overall Local Network / Device Access blocking feature is enabled
+ *
+ * @param enabled flag indicating whether or not the overall local network / device access
+ * blocking feature is enabled
+ * @return The updated instance of {@link GeckoRuntimeSettings}
+ */
+ public @NonNull GeckoRuntimeSettings setLnaEnabled(final boolean enabled) {
+ mLnaEnabled.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Gets whether or not the overall Local Network / Device Access blocking feature is enabled
+ *
+ * @return Boolean indicating whether the overall Local Network / Device Access blocking feature
+ * is enabled or not.
+ */
+ public @Nullable Boolean getLnaEnabled() {
+ return mLnaEnabled.get();
+ }
+
+ /**
+ * Sets whether or not the tracker blocking feature of Local Network / Device Access is enabled
+ *
+ * @param enabled flag indicating whether or not the Local Network / Device Access blocking for
+ * trackers is enabled
+ * @return The updated instance of {@link GeckoRuntimeSettings}
+ */
+ public @NonNull GeckoRuntimeSettings setLnaBlockTrackers(final boolean enabled) {
+ mLnaBlockTrackers.commit(enabled);
+ return this;
+ }
+
+ /**
+ * Gets whether or not the tracker blocking feature of Local Network / Device Access is enabled
+ *
+ * @return Boolean indicating whether the tracker blocking feature Local Network / Device Access
+ * is enabled or not.
+ */
+ public @Nullable Boolean getLnaBlockTrackers() {
+ return mLnaBlockTrackers.get();
+ }
+
/** HTTPS-only mode type definitions for secure browsing. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({ALLOW_ALL, HTTPS_ONLY_PRIVATE, HTTPS_ONLY})
@@ -2032,9 +2146,14 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
*
* @param enabled flag indicating whether or not local network access blocking is enabled
* @return The updated instance of {@link GeckoRuntimeSettings}
+ * @deprecated This API is deprecated and does not work as expected. Please use {@link
+ * #setLnaEnabled(boolean)}, {@link #setLnaBlocking(boolean)} and {@link
+ * #setLnaBlockTrackers(boolean)}} for more fine-grained control.
*/
+ @Deprecated
+ @DeprecationSchedule(id = "deprecated-lna-api", version = 148)
public @NonNull GeckoRuntimeSettings setLnaBlockingEnabled(final boolean enabled) {
- mLnaBlockingEnabled.commit(enabled);
+ mLnaBlocking.commit(enabled);
return this;
}
@@ -2042,9 +2161,14 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
* Gets whether or not local network access (LNA) blocking is enabled
*
* @return Boolean indicating whether LNA blocking is enabled or not.
+ * @deprecated This API is deprecated and does not work as expected. Use {@link #getLnaEnabled()},
+ * {@link #getLnaBlocking()} and {@link #getLnaBlockTrackers()} for more fine-grained control.
*/
+ @Deprecated
+ @DeprecationSchedule(id = "deprecated-lna-api", version = 148)
public boolean getLnaBlockingEnabled() {
- return mLnaBlockingEnabled.get();
+ final Boolean lnaBlocking = mLnaBlocking.get();
+ return lnaBlocking != null ? lnaBlocking : false;
}
/**
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
@@ -13,6 +13,28 @@ exclude: true
⚠️ breaking change and deprecation notices
+## v147
+- Changed Local Network / Device Access APIs in `GeckoRuntimeSettings` & `GeckoRuntimeSettings.Builder` for more granularity
+ - Added new APIs in `GeckoRuntimeSettings`
+ - [`setLnaEnabled`][147.1] & [`getLnaEnabled`][147.2]
+ - [`setLnaBlockTrackers`][147.3] & [`getLnaBlockTrackers`][147.4]
+ - [`setLnaBlocking`][147.5] & [`getLnaBlocking`][147.6]
+ - Added corresponding APIs in `GeckoRuntimeSettings.Builder`
+ - [`setLnaEnabled`][147.7]
+ - [`setLnaBlockTrackers`][147.8]
+ - [`setLnaBlocking`][147.9]
+ - ⚠️ Deprecated `GeckoRuntimeSettings.Builder.setLnaBlockingEnabled`, `GeckoRuntimeSettings.setLnaBlockingEnabled` and `GeckoRuntimeSettings.getLnaBlockingEnabled` APIs.
+
+[147.1]: {{javadoc_uri}}/GeckoRuntimeSettings.html#setLnaEnabled(boolean)
+[147.2]: {{javadoc_uri}}/GeckoRuntimeSettings.html#getLnaEnabled
+[147.3]: {{javadoc_uri}}/GeckoRuntimeSettings.html#setLnaBlockTrackers(boolean)
+[147.4]: {{javadoc_uri}}/GeckoRuntimeSettings.html#getLnaBlockTrackers
+[147.5]: {{javadoc_uri}}/GeckoRuntimeSettings.html#setLnaBlocking(boolean)
+[147.6]: {{javadoc_uri}}/GeckoRuntimeSettings.html#getLnaBlocking
+[147.7]: {{javadoc_uri}}/GeckoRuntimeSettings.Builder.html#setLnaEnabled(boolean)
+[147.8]: {{javadoc_uri}}/GeckoRuntimeSettings.Builder.html#setLnaBlockTrackers(boolean)
+[147.9]: {{javadoc_uri}}/GeckoRuntimeSettings.Builder.html#setLnaBlocking(boolean)
+
## v146
- Added `getSafeBrowsingV5Enabled` and `setSafeBrowsingV5Enabled` to [`ContentBlocking.Settings`][146.1] to control whether to use the SafeBrowsing V5 protocol to access the Google SafeBrowsing service.
- Added [`Autocomplete.AddressStructure`][146.2] API used to retrieve the structure of an address for a given country.
@@ -1855,4 +1877,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]: 0b8df0addbfebea852867d9ded1548f2b365839d
+[api-version]: 1ec5960c50a5a9f6d11f0444d96ad04478fd9857