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

Commit 197e0770 authored by Ziad Youssef's avatar Ziad Youssef Committed by Android (Google) Code Review
Browse files

Merge "Change WebView Package selection logic and error reporting" into main

parents c219f435 ae9ef585
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.webkit;

import static android.webkit.Flags.updateServiceV2;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.UptimeMillisLong;
@@ -33,6 +35,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.Trace;
import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.ArraySet;
import android.util.Log;
@@ -410,6 +413,21 @@ public final class WebViewFactory {
        }
    }

    // Returns whether the given package is enabled.
    // This state can be changed by the user from Settings->Apps
    private static boolean isEnabledPackage(PackageInfo packageInfo) {
        if (packageInfo == null) return false;
        return packageInfo.applicationInfo.enabled;
    }

    // Return {@code true} if the package is installed and not hidden
    private static boolean isInstalledPackage(PackageInfo packageInfo) {
        if (packageInfo == null) return false;
        return (((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0)
                && ((packageInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HIDDEN)
                        == 0));
    }

    @UnsupportedAppUsage
    private static Context getWebViewContextAndSetProvider() throws MissingWebViewPackageException {
        Application initialApplication = AppGlobals.getInitialApplication();
@@ -456,6 +474,21 @@ public final class WebViewFactory {
                Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
            }

            if (updateServiceV2() && !isInstalledPackage(newPackageInfo)) {
                throw new MissingWebViewPackageException(
                        TextUtils.formatSimple(
                                "Current WebView Package (%s) is not installed for the current "
                                + "user",
                                newPackageInfo.packageName));
            }

            if (updateServiceV2() && !isEnabledPackage(newPackageInfo)) {
                throw new MissingWebViewPackageException(
                        TextUtils.formatSimple(
                                "Current WebView Package (%s) is not enabled for the current user",
                                newPackageInfo.packageName));
            }

            // Validate the newly fetched package info, throws MissingWebViewPackageException on
            // failure
            verifyPackageInfo(response.packageInfo, newPackageInfo);
+70 −43
Original line number Diff line number Diff line
@@ -159,11 +159,28 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
        }
    }

    private boolean shouldTriggerRepairLocked() {
        if (mCurrentWebViewPackage == null) {
            return true;
        }
        WebViewProviderInfo defaultProvider = getDefaultWebViewPackage();
        if (mCurrentWebViewPackage.packageName.equals(defaultProvider.packageName)) {
            List<UserPackage> userPackages =
                    mSystemInterface.getPackageInfoForProviderAllUsers(
                            mContext, defaultProvider);
            return !isInstalledAndEnabledForAllUsers(userPackages);
        } else {
            return false;
        }
    }

    @Override
    public void prepareWebViewInSystemServer() {
        try {
            boolean repairNeeded = true;
            synchronized (mLock) {
                mCurrentWebViewPackage = findPreferredWebViewPackage();
                repairNeeded = shouldTriggerRepairLocked();
                String userSetting = mSystemInterface.getUserChosenWebViewProvider(mContext);
                if (userSetting != null
                        && !userSetting.equals(mCurrentWebViewPackage.packageName)) {
@@ -177,25 +194,24 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
                }
                onWebViewProviderChanged(mCurrentWebViewPackage);
            }
        } catch (Throwable t) {
            // Log and discard errors at this stage as we must not crash the system server.
            Slog.e(TAG, "error preparing webview provider from system server", t);
        }

        if (getCurrentWebViewPackage() == null) {
            if (repairNeeded) {
                // We didn't find a valid WebView implementation. Try explicitly re-enabling the
            // fallback package for all users in case it was disabled, even if we already did the
                // default package for all users in case it was disabled, even if we already did the
                // one-time migration before. If this actually changes the state, we will see the
                // PackageManager broadcast shortly and try again.
            WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
            WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
            if (fallbackProvider != null) {
                Slog.w(TAG, "No valid provider, trying to enable " + fallbackProvider.packageName);
                mSystemInterface.enablePackageForAllUsers(mContext, fallbackProvider.packageName,
                                                          true);
            } else {
                Slog.e(TAG, "No valid provider and no fallback available.");
                WebViewProviderInfo defaultProvider = getDefaultWebViewPackage();
                Slog.w(
                        TAG,
                        "No provider available for all users, trying to enable "
                                + defaultProvider.packageName);
                mSystemInterface.enablePackageForAllUsers(
                        mContext, defaultProvider.packageName, true);
            }

        } catch (Throwable t) {
            // Log and discard errors at this stage as we must not crash the system server.
            Slog.e(TAG, "error preparing webview provider from system server", t);
        }
    }

@@ -421,42 +437,43 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {

    /**
     * Returns either the package info of the WebView provider determined in the following way:
     * If the user has chosen a provider then use that if it is valid,
     * otherwise use the first package in the webview priority list that is valid.
     *
     * If the user has chosen a provider then use that if it is valid, enabled and installed
     * for all users, otherwise use the default provider.
     */
    private PackageInfo findPreferredWebViewPackage() throws WebViewPackageMissingException {
        ProviderAndPackageInfo[] providers = getValidWebViewPackagesAndInfos();

        String userChosenProvider = mSystemInterface.getUserChosenWebViewProvider(mContext);

        // If the user has chosen provider, use that (if it's installed and enabled for all
        // users).
        for (ProviderAndPackageInfo providerAndPackage : providers) {
            if (providerAndPackage.provider.packageName.equals(userChosenProvider)) {
                // userPackages can contain null objects.
        String userChosenPackageName = mSystemInterface.getUserChosenWebViewProvider(mContext);
        WebViewProviderInfo userChosenProvider =
                getWebViewProviderForPackage(userChosenPackageName);
        if (userChosenProvider != null) {
            try {
                PackageInfo packageInfo =
                        mSystemInterface.getPackageInfoForProvider(userChosenProvider);
                if (validityResult(userChosenProvider, packageInfo) == VALIDITY_OK) {
                    List<UserPackage> userPackages =
                        mSystemInterface.getPackageInfoForProviderAllUsers(mContext,
                                providerAndPackage.provider);
                            mSystemInterface.getPackageInfoForProviderAllUsers(
                                    mContext, userChosenProvider);
                    if (isInstalledAndEnabledForAllUsers(userPackages)) {
                    return providerAndPackage.packageInfo;
                        return packageInfo;
                    }
                }
            } catch (NameNotFoundException e) {
                Slog.w(TAG, "User chosen WebView package (" + userChosenPackageName
                        + ") not found");
            }

        // User did not choose, or the choice failed; use the most stable provider that is
        // installed and enabled for all users, and available by default (not through
        // user choice).
        for (ProviderAndPackageInfo providerAndPackage : providers) {
            if (providerAndPackage.provider.availableByDefault) {
                // userPackages can contain null objects.
                List<UserPackage> userPackages =
                        mSystemInterface.getPackageInfoForProviderAllUsers(mContext,
                                providerAndPackage.provider);
                if (isInstalledAndEnabledForAllUsers(userPackages)) {
                    return providerAndPackage.packageInfo;
        }

        // User did not choose, or the choice failed; return the default provider even if it is not
        // installed or enabled for all users.
        WebViewProviderInfo defaultProvider = getDefaultWebViewPackage();
        try {
            PackageInfo packageInfo = mSystemInterface.getPackageInfoForProvider(defaultProvider);
            if (validityResult(defaultProvider, packageInfo) == VALIDITY_OK) {
                return packageInfo;
            }
        } catch (NameNotFoundException e) {
            Slog.w(TAG, "Default WebView package (" + defaultProvider.packageName + ") not found");
        }

        // This should never happen during normal operation (only with modified system images).
@@ -464,6 +481,16 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
        throw new WebViewPackageMissingException("Could not find a loadable WebView package");
    }

    private WebViewProviderInfo getWebViewProviderForPackage(String packageName) {
        WebViewProviderInfo[] allProviders = getWebViewPackages();
        for (int n = 0; n < allProviders.length; n++) {
            if (allProviders[n].packageName.equals(packageName)) {
                return allProviders[n];
            }
        }
        return null;
    }

    /**
     * Return true iff {@param packageInfos} point to only installed and enabled packages.
     * The given packages {@param packageInfos} should all be pointing to the same package, but each
+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ public class TestSystemImpl implements SystemInterface {
    private void enablePackageForUser(String packageName, boolean enable, int userId) {
        Map<Integer, PackageInfo> userPackages = mPackages.get(packageName);
        if (userPackages == null) {
            throw new IllegalArgumentException("There is no package called " + packageName);
            return;
        }
        PackageInfo packageInfo = userPackages.get(userId);
        packageInfo.applicationInfo.enabled = enable;
+193 −67

File changed.

Preview size limit exceeded, changes collapsed.