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

Commit c83e3fa3 authored by Gustav Sennton's avatar Gustav Sennton
Browse files

Add fallback packages to be enabled iff no webview packages are valid

This patch makes it possible to declare a WebView package as a fallback
which means that the package will be enabled iff there exist no other
valid and enabled (and available-by-default) webview packages.

The enabled-state of a fallback package is updated at boot and if a
webview package is changed (it it's been up/downgraded or has had its
enabled-state changed).

This patch also adds 'webviewupdate' shell commands for enabling and
disabling this mechanism.

Bug: 26375524, 26375860
Change-Id: I151915e5d6d932697dab10aeb593687e6b9c817e
parent cf7518f7
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -7032,6 +7032,14 @@ public final class Settings {
        public static final String WEBVIEW_DATA_REDUCTION_PROXY_KEY =
                "webview_data_reduction_proxy_key";

        /**
         * Whether or not the WebView fallback mechanism should be enabled.
         * 0=disabled, 1=enabled.
         * @hide
         */
        public static final String WEBVIEW_FALLBACK_LOGIC_ENABLED =
                "webview_fallback_logic_enabled";

        /**
         * Name of the package used as WebView provider (if unset the provider is instead determined
         * by the system).
+18 −3
Original line number Diff line number Diff line
@@ -38,10 +38,14 @@ interface IWebViewUpdateService {
    WebViewProviderResponse waitForAndGetProvider();

    /**
     * DevelopmentSettings uses this to notify WebViewUpdateService that a
     * new provider has been selected by the user.
     * DevelopmentSettings uses this to notify WebViewUpdateService that a new provider has been
     * selected by the user. Returns the provider we end up switching to, this could be different to
     * the one passed as argument to this method since the Dev Setting calling this method could be
     * stale. I.e. the Dev setting could be letting the user choose uninstalled/disabled packages,
     * it would then try to update the provider to such a package while in reality the update
     * service would switch to another one.
     */
    void changeProviderAndSetting(String newProvider);
    String changeProviderAndSetting(String newProvider);

    /**
     * DevelopmentSettings uses this to get the current available WebView
@@ -53,4 +57,15 @@ interface IWebViewUpdateService {
     * Used by DevelopmentSetting to get the name of the WebView provider currently in use.
     */
    String getCurrentWebViewPackageName();

    /**
     * Used by Settings to determine whether a certain package can be enabled/disabled by the user -
     * the package should not be modifiable in this way if it is a fallback package.
     */
    boolean isFallbackPackage(String packageName);

    /**
     * Enable or disable the WebView package fallback mechanism.
     */
    void enableFallbackLogic(boolean enable);
}
+29 −6
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -134,6 +135,7 @@ public final class WebViewFactory {
    // Whether or not the provider must be explicitly chosen by the user to be used.
    private static String TAG_AVAILABILITY = "availableByDefault";
    private static String TAG_SIGNATURE = "signature";
    private static String TAG_FALLBACK = "isFallback";

    /**
     * Reads all signatures at the current depth (within the current provider) from the XML parser.
@@ -159,6 +161,7 @@ public final class WebViewFactory {
     * @hide
     * */
    public static WebViewProviderInfo[] getWebViewPackages() {
        int numFallbackPackages = 0;
        XmlResourceParser parser = null;
        List<WebViewProviderInfo> webViewProviders = new ArrayList<WebViewProviderInfo>();
        try {
@@ -182,13 +185,21 @@ public final class WebViewFactory {
                        throw new MissingWebViewPackageException(
                                "WebView provider in framework resources missing description");
                    }
                    String availableByDefault = parser.getAttributeValue(null, TAG_AVAILABILITY);
                    if (availableByDefault == null) {
                        availableByDefault = "false";
                    }
                    webViewProviders.add(
                    boolean availableByDefault = "true".equals(
                            parser.getAttributeValue(null, TAG_AVAILABILITY));
                    boolean isFallback = "true".equals(
                            parser.getAttributeValue(null, TAG_FALLBACK));
                    WebViewProviderInfo currentProvider =
                            new WebViewProviderInfo(packageName, description, availableByDefault,
                                readSignatures(parser)));
                                isFallback, readSignatures(parser));
                    if (currentProvider.isFallbackPackage()) {
                        numFallbackPackages++;
                        if (numFallbackPackages > 1) {
                            throw new AndroidRuntimeException(
                                    "There can be at most one webview fallback package.");
                        }
                    }
                    webViewProviders.add(currentProvider);
                }
                else {
                    Log.e(LOGTAG, "Found an element that is not a webview provider");
@@ -641,6 +652,18 @@ public final class WebViewFactory {
        return result;
    }

    /**
     * Returns whether the entire package from an ACTION_PACKAGE_CHANGED intent was changed (rather
     * than just one of its components).
     * @hide
     */
    public static boolean entirePackageChanged(Intent intent) {
        String[] componentList =
            intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
        return Arrays.asList(componentList).contains(
                intent.getDataString().substring("package:".length()));
    }

    private static IWebViewUpdateService getUpdateService() {
        return IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate"));
    }
+9 −3
Original line number Diff line number Diff line
@@ -40,11 +40,12 @@ public class WebViewProviderInfo implements Parcelable {
        public WebViewPackageNotFoundException(Exception e) { super(e); }
    }

    public WebViewProviderInfo(String packageName, String description, String availableByDefault,
            String[] signatures) {
    public WebViewProviderInfo(String packageName, String description, boolean availableByDefault,
            boolean isFallback, String[] signatures) {
        this.packageName = packageName;
        this.description = description;
        this.availableByDefault = availableByDefault.equals("true");
        this.availableByDefault = availableByDefault;
        this.isFallback = isFallback;
        this.signatures = signatures;
    }

@@ -114,6 +115,10 @@ public class WebViewProviderInfo implements Parcelable {
        return availableByDefault;
    }

    public boolean isFallbackPackage() {
        return isFallback;
    }

    private void updatePackageInfo() {
        try {
            PackageManager pm = AppGlobals.getInitialApplication().getPackageManager();
@@ -165,6 +170,7 @@ public class WebViewProviderInfo implements Parcelable {
    public String packageName;
    public String description;
    private boolean availableByDefault;
    private boolean isFallback;

    private String[] signatures;

+2 −2
Original line number Diff line number Diff line
@@ -682,8 +682,8 @@
    <string name="select_webview_provider_title">WebView implementation</string>
    <!-- Developer settings: select WebView provider dialog title [CHAR LIMIT=30] -->
    <string name="select_webview_provider_dialog_title">Set WebView implementation</string>
    <!-- Developer settings: confirmation dialog text for the WebView provider selection dialog [CHAR LIMIT=NONE] -->
    <string name="select_webview_provider_confirmation_text">The chosen WebView implementation is disabled, and must be enabled to be used, do you wish to enable it?</string>
    <!-- Developer settings: text for the WebView provider selection toast shown if an invalid provider was chosen (i.e. the setting list was stale). [CHAR LIMIT=NONE] -->
    <string name="select_webview_provider_toast_text">The chosen WebView implementation is invalid because the list of implementation choices grew stale. The list should now be updated.</string>

    <!-- Developer settings screen, convert userdata to file encryption option name -->
    <string name="convert_to_file_encryption">Convert to file encryption</string>
Loading