Loading core/java/android/webkit/WebViewFactory.java +33 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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); Loading services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java +70 −43 Original line number Diff line number Diff line Loading @@ -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)) { Loading @@ -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); } } Loading Loading @@ -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). Loading @@ -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 Loading services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +193 −67 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/webkit/WebViewFactory.java +33 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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); Loading
services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java +70 −43 Original line number Diff line number Diff line Loading @@ -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)) { Loading @@ -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); } } Loading Loading @@ -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). Loading @@ -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 Loading
services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +193 −67 File changed.Preview size limit exceeded, changes collapsed. Show changes