Loading services/core/java/com/android/server/webkit/SystemImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; } services/core/java/com/android/server/webkit/WebViewUpdateService.java +9 −7 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; } Loading @@ -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*/); } Loading services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java +36 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading @@ -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; } Loading Loading @@ -103,7 +107,7 @@ public class WebViewUpdateServiceImpl { } WebViewProviderInfo[] getValidWebViewPackages() { return mWebViewUpdater.getValidWebViewPackages(); return mWebViewUpdater.getValidAndInstalledWebViewPackages(); } WebViewProviderInfo[] getWebViewPackages() { Loading Loading @@ -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 Loading Loading @@ -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) { Loading @@ -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++) { Loading @@ -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; Loading Loading @@ -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)); } } services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +295 −41 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/webkit/SystemImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; }
services/core/java/com/android/server/webkit/WebViewUpdateService.java +9 −7 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; } Loading @@ -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*/); } Loading
services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java +36 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading @@ -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; } Loading Loading @@ -103,7 +107,7 @@ public class WebViewUpdateServiceImpl { } WebViewProviderInfo[] getValidWebViewPackages() { return mWebViewUpdater.getValidWebViewPackages(); return mWebViewUpdater.getValidAndInstalledWebViewPackages(); } WebViewProviderInfo[] getWebViewPackages() { Loading Loading @@ -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 Loading Loading @@ -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) { Loading @@ -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++) { Loading @@ -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; Loading Loading @@ -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)); } }
services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +295 −41 File changed.Preview size limit exceeded, changes collapsed. Show changes