Unhide override user-agent metadata APIs
Relnote: """Add APIs to override user-agent metadata,
We introduced a new API `WebSettingsCompat#setUserAgentMetadata`
to override the user-agent metadata for WebView, which is used to
populate the user-agent client hints, and we also added another
new API `WebSettingsCompat#getUserAgentMetadata` to get current
user-agent overrides. We encourage apps to use the new API to set
the right override values instead of relying on changing user-agent.
"""
This Cl alsp added a demo app for override user-agent metadata.
Bug: b/294183509
Test: :webkit:integration-tests:instrumentation:connectedAndroidTest
Change-Id: I745009a8c24d287416787802fb29210a78967855
diff --git a/webkit/integration-tests/testapp/src/main/AndroidManifest.xml b/webkit/integration-tests/testapp/src/main/AndroidManifest.xml
index d337e48..4b1e168 100644
--- a/webkit/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/webkit/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -142,6 +142,9 @@
<activity
android:name=".ImageDragActivity"
android:exported="false" />
+ <activity
+ android:name=".UserAgentMetadataActivity"
+ android:exported="true" />
<provider
android:authorities="com.example.androidx.webkit.DropDataProvider"
diff --git a/webkit/integration-tests/testapp/src/main/assets/www/user_agent_metadata_main.html b/webkit/integration-tests/testapp/src/main/assets/www/user_agent_metadata_main.html
new file mode 100644
index 0000000..aca6b25
--- /dev/null
+++ b/webkit/integration-tests/testapp/src/main/assets/www/user_agent_metadata_main.html
@@ -0,0 +1,86 @@
+<html>
+<!-- Copyright 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<head>
+ <style>
+ pre.input {
+ color: hsl(300, 24%, 40%);
+ font-style: italic;
+ font-weight: 400;
+ padding-bottom: 0;
+ }
+
+ pre.input::before {
+ content: "> ";
+ color: hsl(300, 24%, 70%);
+ }
+ </style>
+
+ <script type="text/javascript">
+ var xhr = new XMLHttpRequest();
+ xhr.onreadystatechange = function () {
+ if (this.readyState === 4 && this.status === 200) {
+ <!-- Low-entropy client hints -->
+ const brandsText = document.querySelector(".brands");
+ brandsText.textContent = JSON.stringify(navigator.userAgentData.brands, null, " ");
+ const platform = document.querySelector(".platform");
+ platform.textContent = navigator.userAgentData.platform;
+ const mobileText = document.querySelector(".mobile");
+ mobileText.textContent = navigator.userAgentData.mobile ? "true" : "false";
+
+ <!-- High-entropy client hints -->
+ const highEntropyText = document.querySelector(".high-entropy");
+ navigator.userAgentData
+ .getHighEntropyValues([
+ "architecture",
+ "bitness",
+ "brands",
+ "mobile",
+ "model",
+ "platform",
+ "platformVersion",
+ "uaFullVersion",
+ "fullVersionList",
+ ]).then((ua) => {
+ highEntropyText.textContent = JSON.stringify(ua, null, " ");
+ });
+
+ document.querySelector(".user-agent").textContent = navigator.userAgent;
+ }
+ };
+
+ xhr.open("GET", "https://example.com/androidx_webkit/example/assets/www/some_text.html", true);
+ xhr.send();
+ </script>
+</head>
+
+<body>
+ <pre class="input">console.log(navigator.userAgentData.brands);</pre>
+ <pre class="brands" disabled>[…]</pre>
+ <pre class="input">console.log(navigator.userAgentData.mobile);</pre>
+ <pre class="mobile" disabled>[…]</pre>
+ <pre class="input">console.log(navigator.userAgentData.platform);</pre>
+ <pre class="platform" disabled>[…]</pre>
+ <pre class="input">
+ navigator.userAgentData
+ .getHighEntropyValues(["architecture", "bitness", "model", "platform", "platformVersion", "uaFullVersion", "fullVersionList"])
+ .then(ua => { console.log(ua) });</pre
+ >
+ <pre class="high-entropy" disabled></pre>
+ <pre class="input">console.log(navigator.userAgent);</pre>
+ <pre class="user-agent" disabled>[…]</pre>
+</body>
+</html>
diff --git a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/MainActivity.java b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/MainActivity.java
index bf8f85e..7aaf25e 100644
--- a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/MainActivity.java
+++ b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/MainActivity.java
@@ -87,6 +87,9 @@
new MenuListView.MenuItem(
getResources().getString(R.string.image_drag_drop_activity_title),
new Intent(activityContext, ImageDragActivity.class)),
+ new MenuListView.MenuItem(
+ getResources().getString(R.string.user_agent_metadata_activity_title),
+ new Intent(activityContext, UserAgentMetadataActivity.class)),
};
listView.setItems(menuItems);
}
diff --git a/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/UserAgentMetadataActivity.java b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/UserAgentMetadataActivity.java
new file mode 100644
index 0000000..e1213a7
--- /dev/null
+++ b/webkit/integration-tests/testapp/src/main/java/com/example/androidx/webkit/UserAgentMetadataActivity.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.androidx.webkit;
+
+import static androidx.webkit.WebViewAssetLoader.AssetsPathHandler;
+
+import android.annotation.SuppressLint;
+import android.net.Uri;
+import android.os.Bundle;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebResourceResponse;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.webkit.UserAgentMetadata;
+import androidx.webkit.WebSettingsCompat;
+import androidx.webkit.WebViewAssetLoader;
+import androidx.webkit.WebViewFeature;
+
+import java.util.Collections;
+
+/**
+ * Demo activity to demonstrate the behaviour of overriding user-agent metadata APIs.
+ */
+public class UserAgentMetadataActivity extends AppCompatActivity {
+
+ private final Uri mExampleUri = new Uri.Builder()
+ .scheme("https")
+ .authority("example.com")
+ .appendPath("androidx_webkit")
+ .appendPath("example")
+ .appendPath("assets")
+ .build();
+
+ /**
+ * A WebViewClient to intercept the request to mock HTTPS response.
+ */
+ private static class MyWebViewClient extends WebViewClient {
+ private final WebViewAssetLoader mAssetLoader;
+
+ MyWebViewClient(WebViewAssetLoader loader) {
+ mAssetLoader = loader;
+ }
+
+ @Override
+ @RequiresApi(21)
+ public WebResourceResponse shouldInterceptRequest(WebView view,
+ WebResourceRequest request) {
+ return mAssetLoader.shouldInterceptRequest(Api21Impl.getUrl(request));
+ }
+
+ @Override
+ @SuppressWarnings("deprecation") // use the old one for compatibility with all API levels.
+ public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
+ return mAssetLoader.shouldInterceptRequest(Uri.parse(url));
+ }
+ }
+
+ private WebView mWebView;
+
+
+ @SuppressLint("SetJavascriptEnabled")
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_user_agent_metadata);
+
+ setTitle(R.string.user_agent_metadata_activity_title);
+ WebkitHelpers.appendWebViewVersionToTitle(this);
+
+ // Check if override user-agent metadata feature is enabled
+ if (!WebViewFeature.isFeatureSupported(WebViewFeature.USER_AGENT_METADATA)) {
+ WebkitHelpers.showMessageInActivity(this, R.string.webkit_api_not_available);
+ return;
+ }
+
+ mWebView = findViewById(R.id.user_agent_metadata_webview);
+ mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
+ mWebView.getSettings().setJavaScriptEnabled(true);
+
+ RadioGroup radioGroup = findViewById(R.id.user_agent_metadata_radio_group);
+ radioGroup.check(R.id.user_agent_metadata_without_override_mode);
+ radioGroup.setOnCheckedChangeListener(this::onRadioGroupChanged);
+
+ // Initially send a request without overrides
+ refreshView(false);
+ }
+
+ private void refreshView(boolean setOverrides) {
+ UserAgentMetadata overrideSetting;
+ if (setOverrides) {
+ overrideSetting = new UserAgentMetadata.Builder()
+ .setBrandVersionList(Collections.singletonList(
+ new UserAgentMetadata.BrandVersion(
+ "myBrand", "1", "1.1.1.1")))
+ .setFullVersion("1.1.1.1").setPlatform("myPlatform")
+ .setPlatformVersion("2.2.2.2").setArchitecture("myArch")
+ .setMobile(true).setModel("myModel").setBitness(32)
+ .setWow64(false).build();
+
+ } else {
+ overrideSetting = new UserAgentMetadata.Builder().build();
+ }
+ WebSettingsCompat.setUserAgentMetadata(mWebView.getSettings(), overrideSetting);
+
+ // Use WebViewAssetLoader to load html page from app's assets.
+ WebViewAssetLoader assetLoader =
+ new WebViewAssetLoader.Builder()
+ .setDomain("example.com")
+ .addPathHandler(mExampleUri.getPath() + "/", new AssetsPathHandler(this))
+ .build();
+ mWebView.setWebViewClient(new MyWebViewClient(assetLoader));
+ mWebView.loadUrl(Uri.withAppendedPath(mExampleUri,
+ "www/user_agent_metadata_main.html").toString());
+ }
+
+ /**
+ * Handler for selecting w/o user-agent metadata mode through the radio group.
+ * @param unused Triggering radio group
+ * @param checkedId ID of checked radio button
+ */
+ public void onRadioGroupChanged(@NonNull RadioGroup unused, int checkedId) {
+ refreshView(checkedId == R.id.user_agent_metadata_with_override_mode);
+ }
+}
diff --git a/webkit/integration-tests/testapp/src/main/res/layout/activity_user_agent_metadata.xml b/webkit/integration-tests/testapp/src/main/res/layout/activity_user_agent_metadata.xml
new file mode 100644
index 0000000..1223b4e
--- /dev/null
+++ b/webkit/integration-tests/testapp/src/main/res/layout/activity_user_agent_metadata.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/activity_user_agent_metadata"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <TextView
+ android:id="@+id/user_agent_metadata_radio_group_heading"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/user_agent_metadata_override_mode"
+ android:textColor="@color/colorPrimary"
+ android:layout_alignParentTop="true"/>
+ <RadioGroup
+ android:id="@+id/user_agent_metadata_radio_group"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/user_agent_metadata_radio_group_heading">
+ <RadioButton
+ android:id="@+id/user_agent_metadata_without_override_mode"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="48dp"
+ android:text="@string/user_agent_metadata_without_override"
+ android:textColor="@color/colorAccent"/>
+ <RadioButton
+ android:id="@+id/user_agent_metadata_with_override_mode"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="48dp"
+ android:textColor="@color/colorAccent"
+ android:text="@string/user_agent_metadata_with_override"/>
+ </RadioGroup>
+ <WebView
+ android:id="@+id/user_agent_metadata_webview"
+ android:layout_width="match_parent"
+ android:layout_below="@id/user_agent_metadata_radio_group"
+ android:layout_alignParentBottom="true"
+ android:layout_height="0dp"/>
+</RelativeLayout>
\ No newline at end of file
diff --git a/webkit/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml b/webkit/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
index 9ac8144..fa1d0e1 100644
--- a/webkit/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
+++ b/webkit/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
@@ -109,4 +109,10 @@
<string name="requested_with_no_allow_list">Empty</string>
<string name="requested_with_use_allow_list">Containing the web server</string>
+ <!-- User Agent Metadata -->
+ <string name="user_agent_metadata_activity_title">Override User-Agent Metadata</string>
+ <string name="user_agent_metadata_override_mode">User-Agent Metadata</string>
+ <string name="user_agent_metadata_without_override">Without Overrides</string>
+ <string name="user_agent_metadata_with_override">With Overrides</string>
+
</resources>
diff --git a/webkit/webkit/api/current.txt b/webkit/webkit/api/current.txt
index b608615..ebb7e57 100644
--- a/webkit/webkit/api/current.txt
+++ b/webkit/webkit/api/current.txt
@@ -127,6 +127,41 @@
method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
}
+ public final class UserAgentMetadata {
+ method public String? getArchitecture();
+ method public int getBitness();
+ method public java.util.List<androidx.webkit.UserAgentMetadata.BrandVersion!>? getBrandVersionList();
+ method public String? getFullVersion();
+ method public String? getModel();
+ method public String? getPlatform();
+ method public String? getPlatformVersion();
+ method public boolean isMobile();
+ method public boolean isWow64();
+ field public static final int BITNESS_DEFAULT = 0; // 0x0
+ }
+
+ public static final class UserAgentMetadata.BrandVersion {
+ ctor public UserAgentMetadata.BrandVersion(String, String, String);
+ method public String getBrand();
+ method public String getFullVersion();
+ method public String getMajorVersion();
+ }
+
+ public static final class UserAgentMetadata.Builder {
+ ctor public UserAgentMetadata.Builder();
+ ctor public UserAgentMetadata.Builder(androidx.webkit.UserAgentMetadata);
+ method public androidx.webkit.UserAgentMetadata build();
+ method public androidx.webkit.UserAgentMetadata.Builder setArchitecture(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setBitness(int);
+ method public androidx.webkit.UserAgentMetadata.Builder setBrandVersionList(java.util.List<androidx.webkit.UserAgentMetadata.BrandVersion!>);
+ method public androidx.webkit.UserAgentMetadata.Builder setFullVersion(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setMobile(boolean);
+ method public androidx.webkit.UserAgentMetadata.Builder setModel(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setPlatform(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setPlatformVersion(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setWow64(boolean);
+ }
+
public class WebMessageCompat {
ctor @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public WebMessageCompat(byte[]);
ctor @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public WebMessageCompat(byte[], androidx.webkit.WebMessagePortCompat![]?);
@@ -169,6 +204,7 @@
method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList(android.webkit.WebSettings);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.USER_AGENT_METADATA, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.UserAgentMetadata getUserAgentMetadata(android.webkit.WebSettings);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isAlgorithmicDarkeningAllowed(android.webkit.WebSettings);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setAlgorithmicDarkeningAllowed(android.webkit.WebSettings, boolean);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
@@ -178,6 +214,7 @@
method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setRequestedWithHeaderOriginAllowList(android.webkit.WebSettings, java.util.Set<java.lang.String!>);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.USER_AGENT_METADATA, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setUserAgentMetadata(android.webkit.WebSettings, androidx.webkit.UserAgentMetadata);
field @Deprecated public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
field @Deprecated public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
field @Deprecated public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
@@ -297,6 +334,7 @@
field public static final String STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS = "STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS";
field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
+ field public static final String USER_AGENT_METADATA = "USER_AGENT_METADATA";
field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
field public static final String WEB_MESSAGE_ARRAY_BUFFER = "WEB_MESSAGE_ARRAY_BUFFER";
field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
diff --git a/webkit/webkit/api/restricted_current.txt b/webkit/webkit/api/restricted_current.txt
index b608615..ebb7e57 100644
--- a/webkit/webkit/api/restricted_current.txt
+++ b/webkit/webkit/api/restricted_current.txt
@@ -127,6 +127,41 @@
method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
}
+ public final class UserAgentMetadata {
+ method public String? getArchitecture();
+ method public int getBitness();
+ method public java.util.List<androidx.webkit.UserAgentMetadata.BrandVersion!>? getBrandVersionList();
+ method public String? getFullVersion();
+ method public String? getModel();
+ method public String? getPlatform();
+ method public String? getPlatformVersion();
+ method public boolean isMobile();
+ method public boolean isWow64();
+ field public static final int BITNESS_DEFAULT = 0; // 0x0
+ }
+
+ public static final class UserAgentMetadata.BrandVersion {
+ ctor public UserAgentMetadata.BrandVersion(String, String, String);
+ method public String getBrand();
+ method public String getFullVersion();
+ method public String getMajorVersion();
+ }
+
+ public static final class UserAgentMetadata.Builder {
+ ctor public UserAgentMetadata.Builder();
+ ctor public UserAgentMetadata.Builder(androidx.webkit.UserAgentMetadata);
+ method public androidx.webkit.UserAgentMetadata build();
+ method public androidx.webkit.UserAgentMetadata.Builder setArchitecture(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setBitness(int);
+ method public androidx.webkit.UserAgentMetadata.Builder setBrandVersionList(java.util.List<androidx.webkit.UserAgentMetadata.BrandVersion!>);
+ method public androidx.webkit.UserAgentMetadata.Builder setFullVersion(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setMobile(boolean);
+ method public androidx.webkit.UserAgentMetadata.Builder setModel(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setPlatform(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setPlatformVersion(String);
+ method public androidx.webkit.UserAgentMetadata.Builder setWow64(boolean);
+ }
+
public class WebMessageCompat {
ctor @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public WebMessageCompat(byte[]);
ctor @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public WebMessageCompat(byte[], androidx.webkit.WebMessagePortCompat![]?);
@@ -169,6 +204,7 @@
method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList(android.webkit.WebSettings);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.USER_AGENT_METADATA, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.UserAgentMetadata getUserAgentMetadata(android.webkit.WebSettings);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isAlgorithmicDarkeningAllowed(android.webkit.WebSettings);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setAlgorithmicDarkeningAllowed(android.webkit.WebSettings, boolean);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
@@ -178,6 +214,7 @@
method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setRequestedWithHeaderOriginAllowList(android.webkit.WebSettings, java.util.Set<java.lang.String!>);
method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.USER_AGENT_METADATA, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setUserAgentMetadata(android.webkit.WebSettings, androidx.webkit.UserAgentMetadata);
field @Deprecated public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
field @Deprecated public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
field @Deprecated public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
@@ -297,6 +334,7 @@
field public static final String STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS = "STARTUP_FEATURE_SET_DIRECTORY_BASE_PATHS";
field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
+ field public static final String USER_AGENT_METADATA = "USER_AGENT_METADATA";
field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
field public static final String WEB_MESSAGE_ARRAY_BUFFER = "WEB_MESSAGE_ARRAY_BUFFER";
field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
diff --git a/webkit/webkit/src/main/java/androidx/webkit/UserAgentMetadata.java b/webkit/webkit/src/main/java/androidx/webkit/UserAgentMetadata.java
index ca9f828..f799f505 100644
--- a/webkit/webkit/src/main/java/androidx/webkit/UserAgentMetadata.java
+++ b/webkit/webkit/src/main/java/androidx/webkit/UserAgentMetadata.java
@@ -16,6 +16,8 @@
package androidx.webkit;
+import android.annotation.SuppressLint;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
@@ -29,13 +31,8 @@
* <p>
* This class is functionally equivalent to
* <a href="https://wicg.github.io/ua-client-hints/#interface">UADataValues</a>.
- * <p>
- * TODO(b/294183509): unhide
- *
- * @hide
*/
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public class UserAgentMetadata {
+public final class UserAgentMetadata {
/**
* Use this value for bitness to use the platform's default bitness value, which is an empty
* string for Android WebView.
@@ -80,6 +77,7 @@
* @see Builder#setBrandVersionList
*
*/
+ @SuppressLint("NullableCollection")
@Nullable
public List<BrandVersion> getBrandVersionList() {
return mBrandVersionList;
@@ -170,7 +168,8 @@
* <p>
* @see Builder#setWow64
*
- * @return A boolean to indicate whether user-agent's binary is running in 64-bit Windows.
+ * @return A boolean to indicate whether user-agent's binary is running in 32-bit mode on
+ * 64-bit Windows.
*/
public boolean isWow64() {
return mWow64;
@@ -207,12 +206,11 @@
* <a href="https://wicg.github.io/ua-client-hints/#interface">NavigatorUABrandVersion</a>.
*
*/
- public static class BrandVersion {
+ public static final class BrandVersion {
private final String mBrand;
private final String mMajorVersion;
private final String mFullVersion;
- @RestrictTo(RestrictTo.Scope.LIBRARY)
public BrandVersion(@NonNull String brand, @NonNull String majorVersion,
@NonNull String fullVersion) {
if (brand.trim().isEmpty() || majorVersion.trim().isEmpty()
@@ -344,7 +342,9 @@
/**
* Sets user-agent metadata brands and their versions. The brand name, major version and
- * full version should not be blank.
+ * full version should not be blank. The default value is null which means the system
+ * default user-agent metadata brands and versions will be used to generate the
+ * user-agent client hints.
*
* @param brandVersions a list of {@link BrandVersion} used to generated user-agent client
* hints {@code sec-cu-ua} and {@code sec-ch-ua-full-version-list}.
diff --git a/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java b/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
index 9ce9e66..4a544da 100644
--- a/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
+++ b/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
@@ -722,12 +722,9 @@
* {@link WebViewFeature#isFeatureSupported(String)}
* returns true for {@link WebViewFeature#USER_AGENT_METADATA}.
*
+ * @param settings Settings retrieved from {@link WebView#getSettings()}.
* @param metadata the WebView's user-agent metadata.
- *
- * TODO(b/294183509): unhide
- * @hide
*/
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@RequiresFeature(name = WebViewFeature.USER_AGENT_METADATA,
enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public static void setUserAgentMetadata(@NonNull WebSettings settings,
@@ -752,10 +749,8 @@
* {@link WebViewFeature#isFeatureSupported(String)}
* returns true for {@link WebViewFeature#USER_AGENT_METADATA}.
*
- * TODO(b/294183509): unhide
- * @hide
+ * @param settings Settings retrieved from {@link WebView#getSettings()}.
*/
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@RequiresFeature(name = WebViewFeature.USER_AGENT_METADATA,
enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
@NonNull
diff --git a/webkit/webkit/src/main/java/androidx/webkit/WebViewFeature.java b/webkit/webkit/src/main/java/androidx/webkit/WebViewFeature.java
index 81ba5ed..11936ee 100644
--- a/webkit/webkit/src/main/java/androidx/webkit/WebViewFeature.java
+++ b/webkit/webkit/src/main/java/androidx/webkit/WebViewFeature.java
@@ -538,13 +538,9 @@
/**
* Feature for {@link #isFeatureSupported(String)}.
* This feature covers
- * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#getUserAgentMetadata(WebSettings)}, and
- * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#setUserAgentMetadata(WebSettings, UserAgentMetadata)}.
- *
- * TODO(b/294183509): unhide
- * @hide
+ * {@link androidx.webkit.WebSettingsCompat#getUserAgentMetadata(WebSettings)}, and
+ * {@link androidx.webkit.WebSettingsCompat#setUserAgentMetadata(WebSettings, UserAgentMetadata)}.
*/
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public static final String USER_AGENT_METADATA = "USER_AGENT_METADATA";
/**