Loading services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java +41 −12 Original line number Diff line number Diff line Loading @@ -96,6 +96,9 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { private boolean mWebViewPackageDirty = false; private boolean mAnyWebViewInstalled = false; // Keeps track of whether we attempted to repair WebView before. private boolean mAttemptedToRepairBefore = false; private static final int NUMBER_OF_RELROS_UNKNOWN = Integer.MAX_VALUE; // The WebView package currently in use (or the one we are preparing). Loading Loading @@ -136,6 +139,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { boolean removedOrChangedOldPackage = false; String oldProviderName = null; PackageInfo newPackage = null; boolean repairNeeded = false; synchronized (mLock) { try { newPackage = findPreferredWebViewPackage(); Loading @@ -161,6 +165,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { Slog.e(TAG, "Could not find valid WebView package to create relro with " + e); } repairNeeded = shouldTriggerRepairLocked(); } if (updateWebView && !removedOrChangedOldPackage && oldProviderName != null) { Loading @@ -170,12 +175,18 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { // only kills dependents of packages that are being removed. mSystemInterface.killPackageDependents(oldProviderName); } if (repairNeeded) { attemptRepair(); } return; } } } private boolean shouldTriggerRepairLocked() { if (mAttemptedToRepairBefore) { return false; } if (mCurrentWebViewPackage == null) { return true; } Loading @@ -189,6 +200,26 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { } } private void attemptRepair() { // We didn't find a valid WebView implementation. Try explicitly re-installing and // re-enabling the default package for all users in case it was disabled. If this actually // changes the state, we will see the PackageManager broadcast shortly and try again. synchronized (mLock) { if (mAttemptedToRepairBefore) { return; } mAttemptedToRepairBefore = true; } Slog.w( TAG, "No provider available for all users, trying to install and enable " + mDefaultProvider.packageName); mSystemInterface.installExistingPackageForAllUsers( mContext, mDefaultProvider.packageName); mSystemInterface.enablePackageForAllUsers( mContext, mDefaultProvider.packageName, true); } @Override public void prepareWebViewInSystemServer() { try { Loading @@ -211,18 +242,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { } if (repairNeeded) { // We didn't find a valid WebView implementation. Try explicitly re-installing and // re-enabling 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. Slog.w( TAG, "No provider available for all users, trying to install and enable " + mDefaultProvider.packageName); mSystemInterface.installExistingPackageForAllUsers( mContext, mDefaultProvider.packageName); mSystemInterface.enablePackageForAllUsers( mContext, mDefaultProvider.packageName, true); attemptRepair(); } } catch (Throwable t) { Loading Loading @@ -332,6 +352,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { PackageInfo oldPackage = null; PackageInfo newPackage = null; boolean providerChanged = false; boolean repairNeeded = false; synchronized (mLock) { oldPackage = mCurrentWebViewPackage; Loading @@ -354,11 +375,19 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { if (providerChanged) { onWebViewProviderChanged(newPackage); } // Choosing another provider shouldn't break our state. Only check if repair // is needed if this function is called as a result of a user change. if (newProviderName == null) { repairNeeded = shouldTriggerRepairLocked(); } } // Kill apps using the old provider only if we changed provider if (providerChanged && oldPackage != null) { mSystemInterface.killPackageDependents(oldPackage.packageName); } if (repairNeeded) { attemptRepair(); } // Return the new provider, this is not necessarily the one we were asked to switch to, // but the persistent setting will now be pointing to the provider we were asked to // switch to anyway. Loading services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java +6 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,9 @@ public class TestSystemImpl implements SystemInterface { return; } PackageInfo packageInfo = userPackages.get(userId); if (packageInfo == null) { return; } packageInfo.applicationInfo.enabled = enable; setPackageInfoForUser(userId, packageInfo); } Loading @@ -106,6 +109,9 @@ public class TestSystemImpl implements SystemInterface { return; } PackageInfo packageInfo = userPackages.get(userId); if (packageInfo == null) { return; } packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED; packageInfo.applicationInfo.privateFlags &= (~ApplicationInfo.PRIVATE_FLAG_HIDDEN); setPackageInfoForUser(userId, packageInfo); Loading services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +63 −1 Original line number Diff line number Diff line Loading @@ -1551,7 +1551,7 @@ public class WebViewUpdateServiceTest { @Test @RequiresFlagsEnabled("android.webkit.update_service_v2") public void testDefaultWebViewPackageInstalling() { public void testDefaultWebViewPackageInstallingDuringStartUp() { String testPackage = "testDefault"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { Loading @@ -1574,6 +1574,68 @@ public class WebViewUpdateServiceTest { Matchers.anyObject(), Mockito.eq(testPackage)); } @Test @RequiresFlagsEnabled("android.webkit.update_service_v2") public void testDefaultWebViewPackageInstallingAfterStartUp() { String testPackage = "testDefault"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( testPackage, "", true /* default available */, false /* fallback */, null) }; checkCertainPackageUsedAfterWebViewBootPreparation(testPackage, packages); // uninstall the default package. mTestSystemImpl.setPackageInfo( createPackageInfo( testPackage, true /* enabled */, true /* valid */, false /* installed */)); mWebViewUpdateServiceImpl.packageStateChanged(testPackage, WebViewUpdateService.PACKAGE_REMOVED, 0); // Check that we try to re-install the default package. Mockito.verify(mTestSystemImpl) .installExistingPackageForAllUsers( Matchers.anyObject(), Mockito.eq(testPackage)); } /** * Ensures that adding a new user for which the current WebView package is uninstalled triggers * the repair logic. */ @Test @RequiresFlagsEnabled("android.webkit.update_service_v2") public void testAddingNewUserWithDefaultdPackageNotInstalled() { String testPackage = "testDefault"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( testPackage, "", true /* default available */, false /* fallback */, null) }; checkCertainPackageUsedAfterWebViewBootPreparation(testPackage, packages); // Add new user with the default package not installed. int newUser = 100; mTestSystemImpl.addUser(newUser); mTestSystemImpl.setPackageInfoForUser(newUser, createPackageInfo(testPackage, true /* enabled */, true /* valid */, false /* installed */)); mWebViewUpdateServiceImpl.handleNewUser(newUser); // Check that we try to re-install the default package for all users. Mockito.verify(mTestSystemImpl) .installExistingPackageForAllUsers( Matchers.anyObject(), Mockito.eq(testPackage)); } private void testDefaultPackageChosen(PackageInfo packageInfo) { WebViewProviderInfo[] packages = new WebViewProviderInfo[] { Loading Loading
services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl2.java +41 −12 Original line number Diff line number Diff line Loading @@ -96,6 +96,9 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { private boolean mWebViewPackageDirty = false; private boolean mAnyWebViewInstalled = false; // Keeps track of whether we attempted to repair WebView before. private boolean mAttemptedToRepairBefore = false; private static final int NUMBER_OF_RELROS_UNKNOWN = Integer.MAX_VALUE; // The WebView package currently in use (or the one we are preparing). Loading Loading @@ -136,6 +139,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { boolean removedOrChangedOldPackage = false; String oldProviderName = null; PackageInfo newPackage = null; boolean repairNeeded = false; synchronized (mLock) { try { newPackage = findPreferredWebViewPackage(); Loading @@ -161,6 +165,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { Slog.e(TAG, "Could not find valid WebView package to create relro with " + e); } repairNeeded = shouldTriggerRepairLocked(); } if (updateWebView && !removedOrChangedOldPackage && oldProviderName != null) { Loading @@ -170,12 +175,18 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { // only kills dependents of packages that are being removed. mSystemInterface.killPackageDependents(oldProviderName); } if (repairNeeded) { attemptRepair(); } return; } } } private boolean shouldTriggerRepairLocked() { if (mAttemptedToRepairBefore) { return false; } if (mCurrentWebViewPackage == null) { return true; } Loading @@ -189,6 +200,26 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { } } private void attemptRepair() { // We didn't find a valid WebView implementation. Try explicitly re-installing and // re-enabling the default package for all users in case it was disabled. If this actually // changes the state, we will see the PackageManager broadcast shortly and try again. synchronized (mLock) { if (mAttemptedToRepairBefore) { return; } mAttemptedToRepairBefore = true; } Slog.w( TAG, "No provider available for all users, trying to install and enable " + mDefaultProvider.packageName); mSystemInterface.installExistingPackageForAllUsers( mContext, mDefaultProvider.packageName); mSystemInterface.enablePackageForAllUsers( mContext, mDefaultProvider.packageName, true); } @Override public void prepareWebViewInSystemServer() { try { Loading @@ -211,18 +242,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { } if (repairNeeded) { // We didn't find a valid WebView implementation. Try explicitly re-installing and // re-enabling 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. Slog.w( TAG, "No provider available for all users, trying to install and enable " + mDefaultProvider.packageName); mSystemInterface.installExistingPackageForAllUsers( mContext, mDefaultProvider.packageName); mSystemInterface.enablePackageForAllUsers( mContext, mDefaultProvider.packageName, true); attemptRepair(); } } catch (Throwable t) { Loading Loading @@ -332,6 +352,7 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { PackageInfo oldPackage = null; PackageInfo newPackage = null; boolean providerChanged = false; boolean repairNeeded = false; synchronized (mLock) { oldPackage = mCurrentWebViewPackage; Loading @@ -354,11 +375,19 @@ class WebViewUpdateServiceImpl2 implements WebViewUpdateServiceInterface { if (providerChanged) { onWebViewProviderChanged(newPackage); } // Choosing another provider shouldn't break our state. Only check if repair // is needed if this function is called as a result of a user change. if (newProviderName == null) { repairNeeded = shouldTriggerRepairLocked(); } } // Kill apps using the old provider only if we changed provider if (providerChanged && oldPackage != null) { mSystemInterface.killPackageDependents(oldPackage.packageName); } if (repairNeeded) { attemptRepair(); } // Return the new provider, this is not necessarily the one we were asked to switch to, // but the persistent setting will now be pointing to the provider we were asked to // switch to anyway. Loading
services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java +6 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,9 @@ public class TestSystemImpl implements SystemInterface { return; } PackageInfo packageInfo = userPackages.get(userId); if (packageInfo == null) { return; } packageInfo.applicationInfo.enabled = enable; setPackageInfoForUser(userId, packageInfo); } Loading @@ -106,6 +109,9 @@ public class TestSystemImpl implements SystemInterface { return; } PackageInfo packageInfo = userPackages.get(userId); if (packageInfo == null) { return; } packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED; packageInfo.applicationInfo.privateFlags &= (~ApplicationInfo.PRIVATE_FLAG_HIDDEN); setPackageInfoForUser(userId, packageInfo); Loading
services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +63 −1 Original line number Diff line number Diff line Loading @@ -1551,7 +1551,7 @@ public class WebViewUpdateServiceTest { @Test @RequiresFlagsEnabled("android.webkit.update_service_v2") public void testDefaultWebViewPackageInstalling() { public void testDefaultWebViewPackageInstallingDuringStartUp() { String testPackage = "testDefault"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { Loading @@ -1574,6 +1574,68 @@ public class WebViewUpdateServiceTest { Matchers.anyObject(), Mockito.eq(testPackage)); } @Test @RequiresFlagsEnabled("android.webkit.update_service_v2") public void testDefaultWebViewPackageInstallingAfterStartUp() { String testPackage = "testDefault"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( testPackage, "", true /* default available */, false /* fallback */, null) }; checkCertainPackageUsedAfterWebViewBootPreparation(testPackage, packages); // uninstall the default package. mTestSystemImpl.setPackageInfo( createPackageInfo( testPackage, true /* enabled */, true /* valid */, false /* installed */)); mWebViewUpdateServiceImpl.packageStateChanged(testPackage, WebViewUpdateService.PACKAGE_REMOVED, 0); // Check that we try to re-install the default package. Mockito.verify(mTestSystemImpl) .installExistingPackageForAllUsers( Matchers.anyObject(), Mockito.eq(testPackage)); } /** * Ensures that adding a new user for which the current WebView package is uninstalled triggers * the repair logic. */ @Test @RequiresFlagsEnabled("android.webkit.update_service_v2") public void testAddingNewUserWithDefaultdPackageNotInstalled() { String testPackage = "testDefault"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( testPackage, "", true /* default available */, false /* fallback */, null) }; checkCertainPackageUsedAfterWebViewBootPreparation(testPackage, packages); // Add new user with the default package not installed. int newUser = 100; mTestSystemImpl.addUser(newUser); mTestSystemImpl.setPackageInfoForUser(newUser, createPackageInfo(testPackage, true /* enabled */, true /* valid */, false /* installed */)); mWebViewUpdateServiceImpl.handleNewUser(newUser); // Check that we try to re-install the default package for all users. Mockito.verify(mTestSystemImpl) .installExistingPackageForAllUsers( Matchers.anyObject(), Mockito.eq(testPackage)); } private void testDefaultPackageChosen(PackageInfo packageInfo) { WebViewProviderInfo[] packages = new WebViewProviderInfo[] { Loading