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

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

Merge "Attempt to repair the WebView pacakge in more cases" into main

parents 21e89e9b 22f910d5
Loading
Loading
Loading
Loading
+41 −12
Original line number Diff line number Diff line
@@ -96,6 +96,9 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
    private boolean mWebViewPackageDirty = false;
    private boolean mAnyWebViewInstalled = false;

    // Keeps track of whether we attempted to repair WebView before.
    private boolean mAttemptedToRepairBefore = false;

    private static final int NUMBER_OF_RELROS_UNKNOWN = Integer.MAX_VALUE;

    // The WebView package currently in use (or the one we are preparing).
@@ -136,6 +139,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
                boolean removedOrChangedOldPackage = false;
                String oldProviderName = null;
                PackageInfo newPackage = null;
                boolean repairNeeded = false;
                synchronized (mLock) {
                    try {
                        newPackage = findPreferredWebViewPackage();
@@ -161,6 +165,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
                        Slog.e(TAG, "Could not find valid WebView package to create relro with "
                                + e);
                    }
                    repairNeeded = shouldTriggerRepairLocked();
                }
                if (updateWebView && !removedOrChangedOldPackage
                        && oldProviderName != null) {
@@ -170,12 +175,18 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
                    // only kills dependents of packages that are being removed.
                    mSystemInterface.killPackageDependents(oldProviderName);
                }
                if (repairNeeded) {
                    attemptRepair();
                }
                return;
            }
        }
    }

    private boolean shouldTriggerRepairLocked() {
        if (mAttemptedToRepairBefore) {
            return false;
        }
        if (mCurrentWebViewPackage == null) {
            return true;
        }
@@ -189,6 +200,26 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
        }
    }

    private void attemptRepair() {
        // We didn't find a valid WebView implementation. Try explicitly re-installing and
        // re-enabling the default package for all users in case it was disabled. If this actually
        // changes the state, we will see the PackageManager broadcast shortly and try again.
        synchronized (mLock) {
            if (mAttemptedToRepairBefore) {
                return;
            }
            mAttemptedToRepairBefore = true;
        }
        Slog.w(
                TAG,
                "No provider available for all users, trying to install and enable "
                        + mDefaultProvider.packageName);
        mSystemInterface.installExistingPackageForAllUsers(
                mContext, mDefaultProvider.packageName);
        mSystemInterface.enablePackageForAllUsers(
                mContext, mDefaultProvider.packageName, true);
    }

    @Override
    public void prepareWebViewInSystemServer() {
        try {
@@ -211,18 +242,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
            }

            if (repairNeeded) {
                // We didn't find a valid WebView implementation. Try explicitly re-installing and
                // re-enabling 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.
                Slog.w(
                        TAG,
                        "No provider available for all users, trying to install and enable "
                                + mDefaultProvider.packageName);
                mSystemInterface.installExistingPackageForAllUsers(
                        mContext, mDefaultProvider.packageName);
                mSystemInterface.enablePackageForAllUsers(
                        mContext, mDefaultProvider.packageName, true);
                attemptRepair();
            }

        } catch (Throwable t) {
@@ -332,6 +352,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
        PackageInfo oldPackage = null;
        PackageInfo newPackage = null;
        boolean providerChanged = false;
        boolean repairNeeded = false;
        synchronized (mLock) {
            oldPackage = mCurrentWebViewPackage;

@@ -354,11 +375,19 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface {
            if (providerChanged) {
                onWebViewProviderChanged(newPackage);
            }
            // Choosing another provider shouldn't break our state. Only check if repair
            // is needed if this function is called as a result of a user change.
            if (newProviderName == null) {
                repairNeeded = shouldTriggerRepairLocked();
            }
        }
        // Kill apps using the old provider only if we changed provider
        if (providerChanged && oldPackage != null) {
            mSystemInterface.killPackageDependents(oldPackage.packageName);
        }
        if (repairNeeded) {
            attemptRepair();
        }
        // Return the new provider, this is not necessarily the one we were asked to switch to,
        // but the persistent setting will now be pointing to the provider we were asked to
        // switch to anyway.
+6 −0
Original line number Diff line number Diff line
@@ -96,6 +96,9 @@ public class TestSystemImpl implements SystemInterface {
            return;
        }
        PackageInfo packageInfo = userPackages.get(userId);
        if (packageInfo == null) {
            return;
        }
        packageInfo.applicationInfo.enabled = enable;
        setPackageInfoForUser(userId, packageInfo);
    }
@@ -106,6 +109,9 @@ public class TestSystemImpl implements SystemInterface {
            return;
        }
        PackageInfo packageInfo = userPackages.get(userId);
        if (packageInfo == null) {
            return;
        }
        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
        packageInfo.applicationInfo.privateFlags &= (~ApplicationInfo.PRIVATE_FLAG_HIDDEN);
        setPackageInfoForUser(userId, packageInfo);
+63 −1
Original line number Diff line number Diff line
@@ -1551,7 +1551,7 @@ public class WebViewUpdateServiceTest {

    @Test
    @RequiresFlagsEnabled("android.webkit.update_service_v2")
    public void testDefaultWebViewPackageInstalling() {
    public void testDefaultWebViewPackageInstallingDuringStartUp() {
        String testPackage = "testDefault";
        WebViewProviderInfo[] packages =
                new WebViewProviderInfo[] {
@@ -1574,6 +1574,68 @@ public class WebViewUpdateServiceTest {
                        Matchers.anyObject(), Mockito.eq(testPackage));
    }

    @Test
    @RequiresFlagsEnabled("android.webkit.update_service_v2")
    public void testDefaultWebViewPackageInstallingAfterStartUp() {
        String testPackage = "testDefault";
        WebViewProviderInfo[] packages =
                new WebViewProviderInfo[] {
                    new WebViewProviderInfo(
                            testPackage,
                            "",
                            true /* default available */,
                            false /* fallback */,
                            null)
                };
        checkCertainPackageUsedAfterWebViewBootPreparation(testPackage, packages);

        // uninstall the default package.
        mTestSystemImpl.setPackageInfo(
                createPackageInfo(
                        testPackage, true /* enabled */, true /* valid */, false /* installed */));
        mWebViewUpdateServiceImpl.packageStateChanged(testPackage,
                WebViewUpdateService.PACKAGE_REMOVED, 0);

        // Check that we try to re-install the default package.
        Mockito.verify(mTestSystemImpl)
                .installExistingPackageForAllUsers(
                        Matchers.anyObject(), Mockito.eq(testPackage));
    }

    /**
     * Ensures that adding a new user for which the current WebView package is uninstalled triggers
     * the repair logic.
     */
    @Test
    @RequiresFlagsEnabled("android.webkit.update_service_v2")
    public void testAddingNewUserWithDefaultdPackageNotInstalled() {
        String testPackage = "testDefault";
        WebViewProviderInfo[] packages =
                new WebViewProviderInfo[] {
                    new WebViewProviderInfo(
                            testPackage,
                            "",
                            true /* default available */,
                            false /* fallback */,
                            null)
                };
        checkCertainPackageUsedAfterWebViewBootPreparation(testPackage, packages);

        // Add new user with the default package not installed.
        int newUser = 100;
        mTestSystemImpl.addUser(newUser);
        mTestSystemImpl.setPackageInfoForUser(newUser,
                createPackageInfo(testPackage, true /* enabled */, true /* valid */,
                        false /* installed */));

        mWebViewUpdateServiceImpl.handleNewUser(newUser);

        // Check that we try to re-install the default package for all users.
        Mockito.verify(mTestSystemImpl)
                .installExistingPackageForAllUsers(
                        Matchers.anyObject(), Mockito.eq(testPackage));
    }

    private void testDefaultPackageChosen(PackageInfo packageInfo) {
        WebViewProviderInfo[] packages =
                new WebViewProviderInfo[] {