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

Commit 96d27d82 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add shell command for turning on/off WebView multiprocess." into oc-dev

parents 1ef45a8b b265016b
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -733,11 +733,6 @@
    <!-- Services settings screen, setting option summary for the user to go to the screen to view running services  -->
    <string name="runningservices_settings_summary">View and control currently running services</string>

    <!-- Developer settings: enable WebView multiprocess name [CHAR LIMIT=50] -->
    <string name="enable_webview_multiprocess">Multiprocess WebView</string>
    <!-- Developer settings: enable WebView multiprocess summary [CHAR LIMIT=60] -->
    <string name="enable_webview_multiprocess_desc">Run WebView renderers separately</string>

    <!-- Developer settings: select WebView provider title [CHAR LIMIT=30] -->
    <string name="select_webview_provider_title">WebView implementation</string>
    <!-- Developer settings: select WebView provider dialog title [CHAR LIMIT=30] -->
+9 −16
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.webkit.WebViewProviderInfo;
import android.webkit.WebViewProviderResponse;

import java.io.PrintWriter;
import java.lang.Integer;
import java.util.List;

/**
@@ -72,6 +73,9 @@ public class WebViewUpdateServiceImpl {
    private WebViewUpdater mWebViewUpdater;
    final private Context mContext;

    private final static int MULTIPROCESS_SETTING_ON_VALUE = Integer.MAX_VALUE;
    private final static int MULTIPROCESS_SETTING_OFF_VALUE = Integer.MIN_VALUE;

    public WebViewUpdateServiceImpl(Context context, SystemInterface systemInterface) {
        mContext = context;
        mSystemInterface = systemInterface;
@@ -234,31 +238,20 @@ public class WebViewUpdateServiceImpl {
    }

    boolean isMultiProcessEnabled() {
        PackageInfo current = getCurrentWebViewPackage();
        if (current == null) return false;
        int currentVersion = current.versionCode;
        int settingValue = mSystemInterface.getMultiProcessSetting(mContext);
        if (mSystemInterface.isMultiProcessDefaultEnabled()) {
            // Multiprocess should be enabled unless the user has turned it off manually for this
            // version or newer, as we want to re-enable it when it's updated to get fresh
            // bug reports.
            return settingValue > -currentVersion;
            // Multiprocess should be enabled unless the user has turned it off manually.
            return settingValue > MULTIPROCESS_SETTING_OFF_VALUE;
        } else {
            // Multiprocess should not be enabled, unless the user has turned it on manually for
            // any version.
            return settingValue > 0;
            // Multiprocess should not be enabled, unless the user has turned it on manually.
            return settingValue >= MULTIPROCESS_SETTING_ON_VALUE;
        }
    }

    void enableMultiProcess(boolean enable) {
        // The value we store for the setting is the version code of the current package, if it's
        // enabled, or the negation of the version code of the current package, if it's disabled.
        // Users who have a setting from before this scheme was implemented will have it set to 0 or
        // 1 instead.
        PackageInfo current = getCurrentWebViewPackage();
        int currentVersion = current != null ? current.versionCode : 1;
        mSystemInterface.setMultiProcessSetting(mContext,
                                                enable ? currentVersion : -currentVersion);
                enable ? MULTIPROCESS_SETTING_ON_VALUE : MULTIPROCESS_SETTING_OFF_VALUE);
        mSystemInterface.notifyZygote(enable);
        if (current != null) {
            mSystemInterface.killPackageDependents(current.packageName);
+15 −0
Original line number Diff line number Diff line
@@ -43,6 +43,10 @@ class WebViewUpdateServiceShellCommand extends ShellCommand {
                    return enableFallbackLogic(true);
                case "set-webview-implementation":
                    return setWebViewImplementation();
                case "enable-multiprocess":
                    return enableMultiProcess(true);
                case "disable-multiprocess":
                    return enableMultiProcess(false);
                default:
                    return handleDefaultCommands(cmd);
            }
@@ -74,6 +78,13 @@ class WebViewUpdateServiceShellCommand extends ShellCommand {
        }
    }

    private int enableMultiProcess(boolean enable) throws RemoteException {
        final PrintWriter pw = getOutPrintWriter();
        mInterface.enableMultiProcess(enable);
        pw.println("Success");
        return 0;
    }

    @Override
    public void onHelp() {
        PrintWriter pw = getOutPrintWriter();
@@ -90,6 +101,10 @@ class WebViewUpdateServiceShellCommand extends ShellCommand {
        pw.println("    package is available.");
        pw.println("  set-webview-implementation PACKAGE");
        pw.println("    Set the WebView implementation to the specified package.");
        pw.println("  enable-multiprocess");
        pw.println("    Enable multi-process mode for WebView");
        pw.println("  disable-multiprocess");
        pw.println("    Disable multi-process mode for WebView");
        pw.println();
    }
}
+52 −48
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import org.mockito.Mockito;
import org.mockito.Matchers;
import org.mockito.compat.ArgumentMatcher;

import java.lang.Integer;
import java.util.concurrent.CountDownLatch;


@@ -1530,12 +1531,22 @@ public class WebViewUpdateServiceTest {

    @Test
    public void testMultiProcessEnabledByDefault() {
        testMultiProcessByDefault(true /* enabledByDefault */);
    }

    @Test
    public void testMultiProcessDisabledByDefault() {
        testMultiProcessByDefault(false /* enabledByDefault */);
    }

    private void testMultiProcessByDefault(boolean enabledByDefault) {
        String primaryPackage = "primary";
        WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
            new WebViewProviderInfo(
                    primaryPackage, "", true /* default available */, false /* fallback */, null)};
        setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
                          true /* debuggable */, true /* multiprocess by default */);
                          true /* debuggable */,
                          enabledByDefault /* not multiprocess by default */);
        mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
                    true /* valid */, true /* installed */, null /* signatures */,
                    10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
@@ -1544,35 +1555,54 @@ public class WebViewUpdateServiceTest {
        runWebViewBootPreparationOnMainSync();
        checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);

        // Check it's on by default
        assertTrue(mWebViewUpdateServiceImpl.isMultiProcessEnabled());
        // Check it's off by default
        assertEquals(enabledByDefault, mWebViewUpdateServiceImpl.isMultiProcessEnabled());

        // Test toggling it
        mWebViewUpdateServiceImpl.enableMultiProcess(false);
        assertFalse(mWebViewUpdateServiceImpl.isMultiProcessEnabled());
        mWebViewUpdateServiceImpl.enableMultiProcess(true);
        assertTrue(mWebViewUpdateServiceImpl.isMultiProcessEnabled());
        mWebViewUpdateServiceImpl.enableMultiProcess(!enabledByDefault);
        assertEquals(!enabledByDefault, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
        mWebViewUpdateServiceImpl.enableMultiProcess(enabledByDefault);
        assertEquals(enabledByDefault, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
    }

        // Disable, then upgrade provider, which should re-enable it
        mWebViewUpdateServiceImpl.enableMultiProcess(false);
        mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
                    true /* valid */, true /* installed */, null /* signatures */,
                    20 /* lastUpdateTime*/, false /* not hidden */, 2000 /* versionCode */,
                    false /* isSystemApp */));
        mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
                WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
        checkPreparationPhasesForPackage(primaryPackage, 2);
        assertTrue(mWebViewUpdateServiceImpl.isMultiProcessEnabled());
    @Test
    public void testMultiProcessEnabledByDefaultWithSettingsValue() {
        testMultiProcessByDefaultWithSettingsValue(
                true /* enabledByDefault */, Integer.MIN_VALUE, false /* expectEnabled */);
        testMultiProcessByDefaultWithSettingsValue(
                true /* enabledByDefault */, -999999, true /* expectEnabled */);
        testMultiProcessByDefaultWithSettingsValue(
                true /* enabledByDefault */, 0, true /* expectEnabled */);
        testMultiProcessByDefaultWithSettingsValue(
                true /* enabledByDefault */, 999999, true /* expectEnabled */);
    }

    @Test
    public void testMultiProcessDisabledByDefault() {
    public void testMultiProcessDisabledByDefaultWithSettingsValue() {
        testMultiProcessByDefaultWithSettingsValue(
                false /* enabledByDefault */, Integer.MIN_VALUE, false /* expectEnabled */);
        testMultiProcessByDefaultWithSettingsValue(
                false /* enabledByDefault */, 0, false /* expectEnabled */);
        testMultiProcessByDefaultWithSettingsValue(
                false /* enabledByDefault */, 999999, false /* expectEnabled */);
        testMultiProcessByDefaultWithSettingsValue(
                false /* enabledByDefault */, Integer.MAX_VALUE, true /* expectEnabled */);
    }

    /**
     * Test the logic of the multiprocess setting depending on whether multiprocess is enabled by
     * default, and what the setting is set to.
     * @param enabledByDefault whether multiprocess is enabled by default.
     * @param settingValue value of the multiprocess setting.
     */
    private void testMultiProcessByDefaultWithSettingsValue(
            boolean enabledByDefault, int settingValue, boolean expectEnabled) {
        String primaryPackage = "primary";
        WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
            new WebViewProviderInfo(
                    primaryPackage, "", true /* default available */, false /* fallback */, null)};
        setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
                          true /* debuggable */, false /* not multiprocess by default */);
                          true /* debuggable */, enabledByDefault /* multiprocess by default */);
        mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
                    true /* valid */, true /* installed */, null /* signatures */,
                    10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
@@ -1581,38 +1611,12 @@ public class WebViewUpdateServiceTest {
        runWebViewBootPreparationOnMainSync();
        checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);

        // Check it's off by default
        assertFalse(mWebViewUpdateServiceImpl.isMultiProcessEnabled());

        // Test toggling it
        mWebViewUpdateServiceImpl.enableMultiProcess(true);
        assertTrue(mWebViewUpdateServiceImpl.isMultiProcessEnabled());
        mWebViewUpdateServiceImpl.enableMultiProcess(false);
        assertFalse(mWebViewUpdateServiceImpl.isMultiProcessEnabled());

        // Disable, then upgrade provider, which should not re-enable it
        mWebViewUpdateServiceImpl.enableMultiProcess(false);
        mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
                    true /* valid */, true /* installed */, null /* signatures */,
                    20 /* lastUpdateTime*/, false /* not hidden */, 2000 /* versionCode */,
                    false /* isSystemApp */));
        mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
                WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
        checkPreparationPhasesForPackage(primaryPackage, 2);
        assertFalse(mWebViewUpdateServiceImpl.isMultiProcessEnabled());
        mTestSystemImpl.setMultiProcessSetting(null /* context */, settingValue);

        // Enable, then upgrade provider, which should leave it on
        mWebViewUpdateServiceImpl.enableMultiProcess(true);
        mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
                    true /* valid */, true /* installed */, null /* signatures */,
                    30 /* lastUpdateTime*/, false /* not hidden */, 3000 /* versionCode */,
                    false /* isSystemApp */));
        mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
                WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
        checkPreparationPhasesForPackage(primaryPackage, 3);
        assertTrue(mWebViewUpdateServiceImpl.isMultiProcessEnabled());
        assertEquals(expectEnabled, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
    }


    /**
     * Ensure that packages with a targetSdkVersion targeting the current platform are valid, and
     * that packages targeting an older version are not valid.