Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41262a5b authored by Torne (Richard Coles)'s avatar Torne (Richard Coles)
Browse files

WebViewUpdateManager: handle devices without WebView properly.

Devices without FEATURE_WEBVIEW (Wear) don't run the
WebViewUpdateService and so looking up the service binder via
SystemServiceRegistry fails. This returns null in most cases but for
system processes this triggers a WTF, and was causing the Wear settings
app to crash.

Instead of trying to handle WebViewUpdateManager being null, guard all
the usages with an explicit check for whether WebView is supported on
the device, and update the API docs to clarify this requirement.

Bug: 319292658
Bug: 360768638
Test: atest CtsWebkitTestCases
Flag: android.webkit.update_service_ipc_wrapper
Change-Id: I13f0ddde49b3866ceb747a1d1b11e45504f05640
parent 925d1a6f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.PermissionMethod;
import android.annotation.PermissionName;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.StringDef;
import android.annotation.StringRes;
@@ -6677,6 +6678,8 @@ public abstract class Context {
     * Use with {@link #getSystemService(String)} to retrieve a {@link
     * android.webkit.WebViewUpdateManager} for accessing the WebView update service.
     *
     * <p>This can only be used on devices with {@link PackageManager#FEATURE_WEBVIEW}.
     *
     * @see #getSystemService(String)
     * @see android.webkit.WebViewUpdateManager
     * @hide
@@ -6684,6 +6687,7 @@ public abstract class Context {
    @FlaggedApi(android.webkit.Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER)
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @SuppressLint("ServiceName")
    @RequiresFeature(PackageManager.FEATURE_WEBVIEW)
    public static final String WEBVIEW_UPDATE_SERVICE = "webviewupdate";

    /**
+3 −3
Original line number Diff line number Diff line
@@ -3088,11 +3088,11 @@ public class WebView extends AbsoluteLayout
        }

        if (Flags.updateServiceIpcWrapper()) {
            WebViewUpdateManager manager = WebViewUpdateManager.getInstance();
            if (manager == null) {
            if (WebViewFactory.isWebViewSupported()) {
                return WebViewUpdateManager.getInstance().getCurrentWebViewPackage();
            } else {
                return null;
            }
            return manager.getCurrentWebViewPackage();
        } else {
            IWebViewUpdateService service = WebViewFactory.getUpdateService();
            if (service == null) {
+1 −1
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ public final class WebViewFactory {
        public MissingWebViewPackageException(Exception e) { super(e); }
    }

    private static boolean isWebViewSupported() {
    static boolean isWebViewSupported() {
        // No lock; this is a benign race as Boolean's state is final and the PackageManager call
        // will always return the same value.
        if (sWebViewSupported == null) {
+5 −0
Original line number Diff line number Diff line
@@ -19,12 +19,14 @@ package android.webkit;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.SystemServiceRegistry;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.RemoteException;

/** @hide */
@@ -43,8 +45,11 @@ public final class WebViewUpdateManager {
     *
     * This exists for the benefit of callsites without a {@link Context}; prefer
     * {@link Context#getSystemService(Class)} otherwise.
     *
     * This can only be used on devices with {@link PackageManager#FEATURE_WEBVIEW}.
     */
    @SuppressLint("ManagerLookup") // service opts in to getSystemServiceWithNoContext()
    @RequiresFeature(PackageManager.FEATURE_WEBVIEW)
    public static @Nullable WebViewUpdateManager getInstance() {
        return (WebViewUpdateManager) SystemServiceRegistry.getSystemServiceWithNoContext(
                Context.WEBVIEW_UPDATE_SERVICE);
+9 −9
Original line number Diff line number Diff line
@@ -34,11 +34,11 @@ public final class WebViewUpdateService {
     */
    public static WebViewProviderInfo[] getAllWebViewPackages() {
        if (Flags.updateServiceIpcWrapper()) {
            WebViewUpdateManager manager = WebViewUpdateManager.getInstance();
            if (manager == null) {
            if (WebViewFactory.isWebViewSupported()) {
                return WebViewUpdateManager.getInstance().getAllWebViewPackages();
            } else {
                return new WebViewProviderInfo[0];
            }
            return manager.getAllWebViewPackages();
        } else {
            IWebViewUpdateService service = getUpdateService();
            if (service == null) {
@@ -57,11 +57,11 @@ public final class WebViewUpdateService {
     */
    public static WebViewProviderInfo[] getValidWebViewPackages() {
        if (Flags.updateServiceIpcWrapper()) {
            WebViewUpdateManager manager = WebViewUpdateManager.getInstance();
            if (manager == null) {
            if (WebViewFactory.isWebViewSupported()) {
                return WebViewUpdateManager.getInstance().getValidWebViewPackages();
            } else {
                return new WebViewProviderInfo[0];
            }
            return manager.getValidWebViewPackages();
        } else {
            IWebViewUpdateService service = getUpdateService();
            if (service == null) {
@@ -80,11 +80,11 @@ public final class WebViewUpdateService {
     */
    public static String getCurrentWebViewPackageName() {
        if (Flags.updateServiceIpcWrapper()) {
            WebViewUpdateManager manager = WebViewUpdateManager.getInstance();
            if (manager == null) {
            if (WebViewFactory.isWebViewSupported()) {
                return WebViewUpdateManager.getInstance().getCurrentWebViewPackageName();
            } else {
                return null;
            }
            return manager.getCurrentWebViewPackageName();
        } else {
            IWebViewUpdateService service = getUpdateService();
            if (service == null) {
Loading