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

Commit e25c8532 authored by Gustav Sennton's avatar Gustav Sennton Committed by Android (Google) Code Review
Browse files

Merge "Support using uninstalled WebView packages as WebView implementation." into nyc-dev

parents 32d67fab 0df2c556
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -270,5 +270,6 @@ public class SystemImpl implements SystemInterface {

    // flags declaring we want extra info from the package manager for webview providers
    private final static int PACKAGE_FLAGS = PackageManager.GET_META_DATA
            | PackageManager.GET_SIGNATURES | PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
            | PackageManager.GET_SIGNATURES | PackageManager.MATCH_DEBUG_TRIAGED_MISSING
            | PackageManager.MATCH_UNINSTALLED_PACKAGES;
}
+9 −7
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ public class WebViewUpdateService extends SystemService {
        mWebViewUpdatedReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                    switch (intent.getAction()) {
                        case Intent.ACTION_PACKAGE_REMOVED:
                            // When a package is replaced we will receive two intents, one
@@ -73,24 +74,22 @@ public class WebViewUpdateService extends SystemService {
                            // run the update-logic twice.
                            if (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) return;
                            mImpl.packageStateChanged(packageNameFromIntent(intent),
                                    PACKAGE_REMOVED);
                                    PACKAGE_REMOVED, userId);
                            break;
                        case Intent.ACTION_PACKAGE_CHANGED:
                            // Ensure that we only heed PACKAGE_CHANGED intents if they change an
                            // entire package, not just a component
                            if (entirePackageChanged(intent)) {
                                mImpl.packageStateChanged(packageNameFromIntent(intent),
                                        PACKAGE_CHANGED);
                                        PACKAGE_CHANGED, userId);
                            }
                            break;
                        case Intent.ACTION_PACKAGE_ADDED:
                            mImpl.packageStateChanged(packageNameFromIntent(intent),
                                    (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)
                                     ? PACKAGE_ADDED_REPLACED : PACKAGE_ADDED));
                                     ? PACKAGE_ADDED_REPLACED : PACKAGE_ADDED), userId);
                            break;
                        case Intent.ACTION_USER_ADDED:
                            int userId =
                                intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                            mImpl.handleNewUser(userId);
                            break;
                    }
@@ -105,11 +104,14 @@ public class WebViewUpdateService extends SystemService {
        for (WebViewProviderInfo provider : mImpl.getWebViewPackages()) {
            filter.addDataSchemeSpecificPart(provider.packageName, PatternMatcher.PATTERN_LITERAL);
        }
        getContext().registerReceiver(mWebViewUpdatedReceiver, filter);

        getContext().registerReceiverAsUser(mWebViewUpdatedReceiver, UserHandle.ALL, filter,
                null /* broadcast permission */, null /* handler */);

        IntentFilter userAddedFilter = new IntentFilter();
        userAddedFilter.addAction(Intent.ACTION_USER_ADDED);
        getContext().registerReceiver(mWebViewUpdatedReceiver, userAddedFilter);
        getContext().registerReceiverAsUser(mWebViewUpdatedReceiver, UserHandle.ALL,
                userAddedFilter, null /* broadcast permission */, null /* handler */);

        publishBinderService("webviewupdate", new BinderService(), true /*allowIsolated*/);
    }
+36 −11
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.os.UserHandle;
import android.util.Base64;
import android.util.Slog;
import android.webkit.WebViewFactory;
@@ -49,7 +50,10 @@ public class WebViewUpdateServiceImpl {
        mWebViewUpdater = new WebViewUpdater(mContext, mSystemInterface);
    }

    void packageStateChanged(String packageName, int changedState) {
    void packageStateChanged(String packageName, int changedState, int userId) {
        // We don't early out here in different cases where we could potentially early-out (e.g. if
        // we receive PACKAGE_CHANGED for another user than the system user) since that would
        // complicate this logic further and open up for more edge cases.
        updateFallbackStateOnPackageChange(packageName, changedState);
        mWebViewUpdater.packageStateChanged(packageName, changedState);
    }
@@ -64,7 +68,7 @@ public class WebViewUpdateServiceImpl {
            if (provider.availableByDefault && !provider.isFallback) {
                try {
                    PackageInfo packageInfo = mSystemInterface.getPackageInfoForProvider(provider);
                    if (isEnabledPackage(packageInfo)
                    if (isInstalledPackage(packageInfo) && isEnabledPackage(packageInfo)
                            && mWebViewUpdater.isValidProvider(provider, packageInfo)) {
                        return true;
                    }
@@ -103,7 +107,7 @@ public class WebViewUpdateServiceImpl {
    }

    WebViewProviderInfo[] getValidWebViewPackages() {
        return mWebViewUpdater.getValidWebViewPackages();
        return mWebViewUpdater.getValidAndInstalledWebViewPackages();
    }

    WebViewProviderInfo[] getWebViewPackages() {
@@ -254,6 +258,12 @@ public class WebViewUpdateServiceImpl {
                                    // (not if it has been enabled/disabled).
                                    return;
                                }
                                if (newPackage.packageName.equals(oldProviderName)
                                        && (newPackage.lastUpdateTime
                                            == mCurrentWebViewPackage.lastUpdateTime)) {
                                    // If the chosen package hasn't been updated, then early-out
                                    return;
                                }
                            }
                            // Only trigger update actions if the updated package is the one
                            // that will be used, or the one that was in use before the
@@ -373,14 +383,15 @@ public class WebViewUpdateServiceImpl {
            }
        }

        private ProviderAndPackageInfo[] getValidWebViewPackagesAndInfos() {
        private ProviderAndPackageInfo[] getValidWebViewPackagesAndInfos(boolean onlyInstalled) {
            WebViewProviderInfo[] allProviders = mSystemInterface.getWebViewPackages();
            List<ProviderAndPackageInfo> providers = new ArrayList<>();
            for(int n = 0; n < allProviders.length; n++) {
                try {
                    PackageInfo packageInfo =
                        mSystemInterface.getPackageInfoForProvider(allProviders[n]);
                    if (isValidProvider(allProviders[n], packageInfo)) {
                    if ((!onlyInstalled || isInstalledPackage(packageInfo))
                            && isValidProvider(allProviders[n], packageInfo)) {
                        providers.add(new ProviderAndPackageInfo(allProviders[n], packageInfo));
                    }
                } catch (NameNotFoundException e) {
@@ -393,8 +404,9 @@ public class WebViewUpdateServiceImpl {
        /**
         * Fetch only the currently valid WebView packages.
         **/
        public WebViewProviderInfo[] getValidWebViewPackages() {
            ProviderAndPackageInfo[] providersAndPackageInfos = getValidWebViewPackagesAndInfos();
        public WebViewProviderInfo[] getValidAndInstalledWebViewPackages() {
            ProviderAndPackageInfo[] providersAndPackageInfos =
                getValidWebViewPackagesAndInfos(true /* only fetch installed packages */);
            WebViewProviderInfo[] providers =
                new WebViewProviderInfo[providersAndPackageInfos.length];
            for(int n = 0; n < providersAndPackageInfos.length; n++) {
@@ -421,29 +433,33 @@ public class WebViewUpdateServiceImpl {
         *
         */
        private PackageInfo findPreferredWebViewPackage() {
            ProviderAndPackageInfo[] providers = getValidWebViewPackagesAndInfos();
            ProviderAndPackageInfo[] providers =
                getValidWebViewPackagesAndInfos(false /* onlyInstalled */);

            String userChosenProvider = mSystemInterface.getUserChosenWebViewProvider(mContext);

            // If the user has chosen provider, use that
            for (ProviderAndPackageInfo providerAndPackage : providers) {
                if (providerAndPackage.provider.packageName.equals(userChosenProvider)
                        && isInstalledPackage(providerAndPackage.packageInfo)
                        && isEnabledPackage(providerAndPackage.packageInfo)) {
                    return providerAndPackage.packageInfo;
                }
            }

            // User did not choose, or the choice failed; use the most stable provider that is
            // enabled and available by default (not through user choice).
            // installed and enabled for the device owner, and available by default (not through
            // user choice).
            for (ProviderAndPackageInfo providerAndPackage : providers) {
                if (providerAndPackage.provider.availableByDefault
                        && isInstalledPackage(providerAndPackage.packageInfo)
                        && isEnabledPackage(providerAndPackage.packageInfo)) {
                    return providerAndPackage.packageInfo;
                }
            }

            // Could not find any enabled package either, use the most stable and default-available
            // provider.
            // Could not find any installed and enabled package either, use the most stable and
            // default-available provider.
            for (ProviderAndPackageInfo providerAndPackage : providers) {
                if (providerAndPackage.provider.availableByDefault) {
                    return providerAndPackage.packageInfo;
@@ -642,4 +658,13 @@ public class WebViewUpdateServiceImpl {
        return packageInfo.applicationInfo.enabled;
    }

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

}
+295 −41

File changed.

Preview size limit exceeded, changes collapsed.