package com.android.server.webkit;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
-import android.content.pm.Signature;
import android.os.UserHandle;
-import android.util.Slog;
-import android.webkit.UserPackage;
import android.webkit.WebViewProviderInfo;
import android.webkit.WebViewProviderResponse;
import java.io.PrintWriter;
-import java.lang.Integer;
-import java.util.List;
/**
* Implementation of the WebViewUpdateService.
* This class doesn't depend on the android system like the actual Service does and can be used
* directly by tests (as long as they implement a SystemInterface).
*
- * This class implements two main features - handling WebView fallback packages and keeping track
- * of, and preparing, the current WebView implementation. The fallback mechanism is meant to be
- * uncoupled from the rest of the WebView preparation and does not store any state. The code for
- * choosing and preparing a WebView implementation needs to keep track of a couple of different
- * things such as what package is used as WebView implementation.
+ * This class keeps track of and prepares the current WebView implementation, and needs to keep
+ * track of a couple of different things such as what package is used as WebView implementation.
*
* The public methods in this class are accessed from WebViewUpdateService either on the UI thread
- * or on one of multiple Binder threads. This means that the code in this class needs to be
- * thread-safe. The fallback mechanism shares (almost) no information between threads which makes
- * it easier to argue about thread-safety (in theory, if timed badly, the fallback mechanism can
- * incorrectly enable/disable a fallback package but that fault will be corrected when we later
- * receive an intent for that enabling/disabling). On the other hand, the WebView preparation code
- * shares state between threads meaning that code that chooses a new WebView implementation or
- * checks which implementation is being used needs to hold a lock.
+ * or on one of multiple Binder threads. The WebView preparation code shares state between threads
+ * meaning that code that chooses a new WebView implementation or checks which implementation is
+ * being used needs to hold a lock.
*
* The WebViewUpdateService can be accessed in a couple of different ways.
* 1. It is started from the SystemServer at boot - at that point we just initiate some state such
* as the WebView preparation class.
* 2. The SystemServer calls WebViewUpdateService.prepareWebViewInSystemServer. This happens at boot
* and the WebViewUpdateService should not have been accessed before this call. In this call we
- * enable/disable fallback packages and then choose WebView implementation for the first time.
+ * migrate away from the old fallback logic if necessary and then choose WebView implementation for
+ * the first time.
* 3. The update service listens for Intents related to package installs and removals. These intents
- * are received and processed on the UI thread. Each intent can result in enabling/disabling
- * fallback packages and changing WebView implementation.
+ * are received and processed on the UI thread. Each intent can result in changing WebView
+ * implementation.
* 4. The update service can be reached through Binder calls which are handled on specific binder
* threads. These calls can be made from any process. Generally they are used for changing WebView
* implementation (from Settings), getting information about the current WebView implementation (for
// 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);
}
void prepareWebViewInSystemServer() {
- updateFallbackStateOnBoot();
+ migrateFallbackStateOnBoot();
mWebViewUpdater.prepareWebViewInSystemServer();
mSystemInterface.notifyZygote(isMultiProcessEnabled());
}
- private boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) {
- for (WebViewProviderInfo provider : providers) {
- if (provider.availableByDefault && !provider.isFallback) {
- // userPackages can contain null objects.
- List<UserPackage> userPackages =
- mSystemInterface.getPackageInfoForProviderAllUsers(mContext, provider);
- if (WebViewUpdater.isInstalledAndEnabledForAllUsers(userPackages) &&
- // Checking validity of the package for the system user (rather than all
- // users) since package validity depends not on the user but on the package
- // itself.
- mWebViewUpdater.isValidProvider(provider,
- userPackages.get(UserHandle.USER_SYSTEM).getPackageInfo())) {
- return true;
- }
- }
- }
- return false;
- }
-
void handleNewUser(int userId) {
// The system user is always started at boot, and by that point we have already run one
// round of the package-changing logic (through prepareWebViewInSystemServer()), so early
}
/**
- * Called when a user was added or removed to ensure fallback logic and WebView preparation are
- * triggered. This has to be done since the WebView package we use depends on the enabled-state
+ * Called when a user was added or removed to ensure WebView preparation is triggered.
+ * This has to be done since the WebView package we use depends on the enabled-state
* of packages for all users (so adding or removing a user might cause us to change package).
*/
private void handleUserChange() {
- if (mSystemInterface.isFallbackLogicEnabled()) {
- updateFallbackState(mSystemInterface.getWebViewPackages());
- }
// Potentially trigger package-changing logic.
mWebViewUpdater.updateCurrentWebViewPackage(null);
}
return mWebViewUpdater.getCurrentWebViewPackage();
}
- void enableFallbackLogic(boolean enable) {
- mSystemInterface.enableFallbackLogic(enable);
- }
-
- private void updateFallbackStateOnBoot() {
- if (!mSystemInterface.isFallbackLogicEnabled()) return;
-
- WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
- updateFallbackState(webviewProviders);
- }
-
/**
- * Handle the enabled-state of our fallback package, i.e. if there exists some non-fallback
- * package that is valid (and available by default) then disable the fallback package,
- * otherwise, enable the fallback package.
+ * If the fallback logic is enabled, re-enable any fallback package for all users, then
+ * disable the fallback logic.
+ *
+ * This migrates away from the old fallback mechanism to the new state where packages are never
+ * automatically enableenableisabled.
*/
- private void updateFallbackStateOnPackageChange(String changedPackage, int changedState) {
+ private void migrateFallbackStateOnBoot() {
if (!mSystemInterface.isFallbackLogicEnabled()) return;
WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
-
- // A package was changed / updated / downgraded, early out if it is not one of the
- // webview packages that are available by default.
- boolean changedPackageAvailableByDefault = false;
- for (WebViewProviderInfo provider : webviewProviders) {
- if (provider.packageName.equals(changedPackage)) {
- if (provider.availableByDefault) {
- changedPackageAvailableByDefault = true;
- }
- break;
- }
- }
- if (!changedPackageAvailableByDefault) return;
- updateFallbackState(webviewProviders);
- }
-
- private void updateFallbackState(WebViewProviderInfo[] webviewProviders) {
- // If there exists a valid and enabled non-fallback package - disable the fallback
- // package, otherwise, enable it.
WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
- if (fallbackProvider == null) return;
- boolean existsValidNonFallbackProvider = existsValidNonFallbackProvider(webviewProviders);
-
- List<UserPackage> userPackages =
- mSystemInterface.getPackageInfoForProviderAllUsers(mContext, fallbackProvider);
- if (existsValidNonFallbackProvider && !isDisabledForAllUsers(userPackages)) {
- mSystemInterface.uninstallAndDisablePackageForAllUsers(mContext,
- fallbackProvider.packageName);
- } else if (!existsValidNonFallbackProvider
- && !WebViewUpdater.isInstalledAndEnabledForAllUsers(userPackages)) {
- // Enable the fallback package for all users.
- mSystemInterface.enablePackageForAllUsers(mContext,
- fallbackProvider.packageName, true);
+ if (fallbackProvider != null) {
+ mSystemInterface.enablePackageForAllUsers(mContext, fallbackProvider.packageName, true);
}
+ mSystemInterface.enableFallbackLogic(false);
}
/**
return null;
}
- boolean isFallbackPackage(String packageName) {
- if (packageName == null || !mSystemInterface.isFallbackLogicEnabled()) return false;
-
- WebViewProviderInfo[] webviewPackages = mSystemInterface.getWebViewPackages();
- WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewPackages);
- return (fallbackProvider != null
- && packageName.equals(fallbackProvider.packageName));
- }
-
boolean isMultiProcessEnabled() {
int settingValue = mSystemInterface.getMultiProcessSetting(mContext);
if (mSystemInterface.isMultiProcessDefaultEnabled()) {
}
}
- private static boolean isDisabledForAllUsers(List<UserPackage> userPackages) {
- for (UserPackage userPackage : userPackages) {
- if (userPackage.getPackageInfo() != null && userPackage.isEnabledPackage()) {
- return false;
- }
- }
- return true;
- }
-
/**
* Dump the state of this Service.
*/
import org.mockito.Matchers;
import org.mockito.Mockito;
-import java.lang.Integer;
import java.util.concurrent.CountDownLatch;
/**
}
private void setupWithPackages(WebViewProviderInfo[] packages) {
- setupWithPackages(packages, true);
+ setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */,
+ true /* isDebuggable */, false /* multiProcessDefault */);
}
- private void setupWithPackages(WebViewProviderInfo[] packages,
- boolean fallbackLogicEnabled) {
- setupWithPackages(packages, fallbackLogicEnabled, 1);
+ private void setupWithPackagesAndFallbackLogic(WebViewProviderInfo[] packages) {
+ setupWithAllParameters(packages, true /* fallbackLogicEnabled */, 1 /* numRelros */,
+ true /* isDebuggable */, false /* multiProcessDefault */);
}
- private void setupWithPackages(WebViewProviderInfo[] packages,
- boolean fallbackLogicEnabled, int numRelros) {
- setupWithPackages(packages, fallbackLogicEnabled, numRelros,
- true /* isDebuggable == true -> don't check package signatures */);
+ private void setupWithPackagesAndRelroCount(WebViewProviderInfo[] packages, int numRelros) {
+ setupWithAllParameters(packages, false /* fallbackLogicEnabled */, numRelros,
+ true /* isDebuggable */, false /* multiProcessDefault */);
}
- private void setupWithPackages(WebViewProviderInfo[] packages,
- boolean fallbackLogicEnabled, int numRelros, boolean isDebuggable) {
- setupWithPackages(packages, fallbackLogicEnabled, numRelros, isDebuggable,
- false /* multiProcessDefault */);
+ private void setupWithPackagesNonDebuggable(WebViewProviderInfo[] packages) {
+ setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */,
+ false /* isDebuggable */, false /* multiProcessDefault */);
}
- private void setupWithPackages(WebViewProviderInfo[] packages,
+ private void setupWithPackagesAndMultiProcess(WebViewProviderInfo[] packages,
+ boolean multiProcessDefault) {
+ setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */,
+ true /* isDebuggable */, multiProcessDefault);
+ }
+
+ private void setupWithAllParameters(WebViewProviderInfo[] packages,
boolean fallbackLogicEnabled, int numRelros, boolean isDebuggable,
boolean multiProcessDefault) {
TestSystemImpl testing = new TestSystemImpl(packages, fallbackLogicEnabled, numRelros,
private void checkCertainPackageUsedAfterWebViewBootPreparation(String expectedProviderName,
WebViewProviderInfo[] webviewPackages, int numRelros) {
- setupWithPackages(webviewPackages, true, numRelros);
+ setupWithPackagesAndRelroCount(webviewPackages, numRelros);
// Add (enabled and valid) package infos for each provider
setEnabledAndValidPackageInfos(webviewPackages);
Base64.encodeToString(
validSignature.toByteArray(), Base64.DEFAULT)})
};
- setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
- false /* isDebuggable */);
+ setupWithPackagesNonDebuggable(packages);
mTestSystemImpl.setPackageInfo(createPackageInfo(invalidPackage, true /* enabled */,
true /* valid */, true /* installed */, new Signature[]{invalidPackageSignature}
, 0 /* updateTime */));
}
}
+ /**
+ * Scenario for testing migrating away from the fallback logic.
+ * We start with a primary package that's a disabled fallback, and an enabled secondary,
+ * so that the fallback being re-enabled will cause a provider switch, as that covers
+ * the most complex case.
+ */
@Test
- public void testRunFallbackLogicIfEnabled() {
- checkFallbackLogicBeingRun(true);
- }
-
- @Test
- public void testDontRunFallbackLogicIfDisabled() {
- checkFallbackLogicBeingRun(false);
- }
-
- private void checkFallbackLogicBeingRun(boolean fallbackLogicEnabled) {
+ public void testFallbackLogicMigration() {
String primaryPackage = "primary";
- String fallbackPackage = "fallback";
+ String secondaryPackage = "secondary";
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo(
- primaryPackage, "", true /* default available */, false /* fallback */, null),
+ primaryPackage, "", true /* default available */, true /* fallback */, null),
new WebViewProviderInfo(
- fallbackPackage, "", true /* default available */, true /* fallback */, null)};
- setupWithPackages(packages, fallbackLogicEnabled);
- setEnabledAndValidPackageInfos(packages);
+ secondaryPackage, "", true /* default available */, false /* fallback */,
+ null)};
+ setupWithPackagesAndFallbackLogic(packages);
+ mTestSystemImpl.setPackageInfo(
+ createPackageInfo(primaryPackage, false /* enabled */ , true /* valid */,
+ true /* installed */));
+ mTestSystemImpl.setPackageInfo(
+ createPackageInfo(secondaryPackage, true /* enabled */ , true /* valid */,
+ true /* installed */));
+ // Check that the boot time logic re-enables and chooses the primary, and disables the
+ // fallback logic.
runWebViewBootPreparationOnMainSync();
- // Verify that we disable the fallback package if fallback logic enabled, and don't disable
- // the fallback package if that logic is disabled
- if (fallbackLogicEnabled) {
- Mockito.verify(mTestSystemImpl).uninstallAndDisablePackageForAllUsers(
- Matchers.anyObject(), Mockito.eq(fallbackPackage));
- } else {
- Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
- Matchers.anyObject(), Matchers.anyObject());
- }
- Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
- Mockito.argThat(new IsPackageInfoWithName(primaryPackage)));
+ Mockito.verify(mTestSystemImpl).enablePackageForAllUsers(
+ Matchers.anyObject(), Mockito.eq(primaryPackage), Mockito.eq(true));
+ checkPreparationPhasesForPackage(primaryPackage, 1);
+ assertFalse(mTestSystemImpl.isFallbackLogicEnabled());
- // Enable fallback package
- mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
+ // Disable primary again
+ mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, false /* enabled */,
true /* valid */, true /* installed */));
- mWebViewUpdateServiceImpl.packageStateChanged(
- fallbackPackage, WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
+ mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
+ WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
+ checkPreparationPhasesForPackage(secondaryPackage, 1);
- if (fallbackLogicEnabled) {
- // Check that we have now disabled the fallback package twice
- Mockito.verify(mTestSystemImpl, Mockito.times(2)).uninstallAndDisablePackageForAllUsers(
- Matchers.anyObject(), Mockito.eq(fallbackPackage));
- } else {
- // Check that we still haven't disabled any package
- Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
- Matchers.anyObject(), Matchers.anyObject());
- }
+ // Run boot logic again and check that we didn't re-enable the primary a second time.
+ runWebViewBootPreparationOnMainSync();
+ Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForAllUsers(
+ Matchers.anyObject(), Mockito.eq(primaryPackage), Mockito.eq(true));
+ checkPreparationPhasesForPackage(secondaryPackage, 2);
}
/**
- * Scenario for installing primary package when fallback enabled.
- * 1. Start with only fallback installed
- * 2. Install non-fallback
- * 3. Fallback should be disabled
+ * Scenario for installing primary package when secondary in use.
+ * 1. Start with only secondary installed
+ * 2. Install primary
+ * 3. Primary should be used
*/
@Test
- public void testInstallingNonFallbackPackage() {
+ public void testInstallingPrimaryPackage() {
String primaryPackage = "primary";
- String fallbackPackage = "fallback";
+ String secondaryPackage = "secondary";
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo(
primaryPackage, "", true /* default available */, false /* fallback */, null),
new WebViewProviderInfo(
- fallbackPackage, "", true /* default available */, true /* fallback */, null)};
- setupWithPackages(packages, true /* isFallbackLogicEnabled */);
+ secondaryPackage, "", true /* default available */, false /* fallback */,
+ null)};
+ setupWithPackages(packages);
mTestSystemImpl.setPackageInfo(
- createPackageInfo(fallbackPackage, true /* enabled */ , true /* valid */,
+ createPackageInfo(secondaryPackage, true /* enabled */ , true /* valid */,
true /* installed */));
runWebViewBootPreparationOnMainSync();
- Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
- Matchers.anyObject(), Matchers.anyObject());
-
- checkPreparationPhasesForPackage(fallbackPackage,
+ checkPreparationPhasesForPackage(secondaryPackage,
1 /* first preparation for this package*/);
// Install primary package
mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
- // Verify fallback disabled, primary package used as provider, and fallback package killed
- Mockito.verify(mTestSystemImpl).uninstallAndDisablePackageForAllUsers(
- Matchers.anyObject(), Mockito.eq(fallbackPackage));
+ // Verify primary package used as provider, and secondary package killed
checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation for this package*/);
- Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(fallbackPackage));
+ Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(secondaryPackage));
}
@Test
- public void testFallbackChangesEnabledStateSingleUser() {
+ public void testRemovingPrimarySelectsSecondarySingleUser() {
for (PackageRemovalType removalType : REMOVAL_TYPES) {
- checkFallbackChangesEnabledState(false /* multiUser */, removalType);
+ checkRemovingPrimarySelectsSecondary(false /* multiUser */, removalType);
}
}
@Test
- public void testFallbackChangesEnabledStateMultiUser() {
+ public void testRemovingPrimarySelectsSecondaryMultiUser() {
for (PackageRemovalType removalType : REMOVAL_TYPES) {
- checkFallbackChangesEnabledState(true /* multiUser */, removalType);
+ checkRemovingPrimarySelectsSecondary(true /* multiUser */, removalType);
}
}
private PackageRemovalType[] REMOVAL_TYPES = PackageRemovalType.class.getEnumConstants();
- public void checkFallbackChangesEnabledState(boolean multiUser,
+ public void checkRemovingPrimarySelectsSecondary(boolean multiUser,
PackageRemovalType removalType) {
String primaryPackage = "primary";
- String fallbackPackage = "fallback";
+ String secondaryPackage = "secondary";
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo(
primaryPackage, "", true /* default available */, false /* fallback */, null),
new WebViewProviderInfo(
- fallbackPackage, "", true /* default available */, true /* fallback */, null)};
- setupWithPackages(packages, true /* fallbackLogicEnabled */);
+ secondaryPackage, "", true /* default available */, false /* fallback */,
+ null)};
+ setupWithPackages(packages);
int secondaryUserId = 10;
int userIdToChangePackageFor = multiUser ? secondaryUserId : TestSystemImpl.PRIMARY_USER_ID;
if (multiUser) {
setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
runWebViewBootPreparationOnMainSync();
-
- // Verify fallback disabled at boot when primary package enabled
- checkEnablePackageForUserCalled(fallbackPackage, false, multiUser
- ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
- : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */);
-
checkPreparationPhasesForPackage(primaryPackage, 1);
boolean enabled = !(removalType == PackageRemovalType.DISABLE);
boolean installed = !(removalType == PackageRemovalType.UNINSTALL);
boolean hidden = (removalType == PackageRemovalType.HIDE);
- // Disable primary package and ensure fallback becomes enabled and used
+ // Disable primary package and ensure secondary becomes used
mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
createPackageInfo(primaryPackage, enabled /* enabled */, true /* valid */,
installed /* installed */, null /* signature */, 0 /* updateTime */,
removalType == PackageRemovalType.DISABLE
? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_REMOVED,
userIdToChangePackageFor); // USER ID
+ checkPreparationPhasesForPackage(secondaryPackage, 1);
- checkEnablePackageForUserCalled(fallbackPackage, true, multiUser
- ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
- : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */);
-
- checkPreparationPhasesForPackage(fallbackPackage, 1);
-
-
- // Again enable primary package and verify primary is used and fallback becomes disabled
+ // Again enable primary package and verify primary is used
mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
true /* installed */));
removalType == PackageRemovalType.DISABLE
? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_ADDED,
userIdToChangePackageFor);
-
- // Verify fallback is disabled a second time when primary package becomes enabled
- checkEnablePackageForUserCalled(fallbackPackage, false, multiUser
- ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
- : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 2 /* numUsages */);
-
checkPreparationPhasesForPackage(primaryPackage, 2);
}
- private void checkEnablePackageForUserCalled(String packageName, boolean expectEnabled,
- int[] userIds, int numUsages) {
- for (int userId : userIds) {
- Mockito.verify(mTestSystemImpl, Mockito.times(numUsages)).enablePackageForUser(
- Mockito.eq(packageName), Mockito.eq(expectEnabled), Mockito.eq(userId));
- }
- }
-
- @Test
- public void testAddUserWhenFallbackLogicEnabled() {
- checkAddingNewUser(true);
- }
-
- @Test
- public void testAddUserWhenFallbackLogicDisabled() {
- checkAddingNewUser(false);
- }
-
- public void checkAddingNewUser(boolean fallbackLogicEnabled) {
- String primaryPackage = "primary";
- String fallbackPackage = "fallback";
- WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
- new WebViewProviderInfo(
- primaryPackage, "", true /* default available */, false /* fallback */, null),
- new WebViewProviderInfo(
- fallbackPackage, "", true /* default available */, true /* fallback */, null)};
- setupWithPackages(packages, fallbackLogicEnabled);
- setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
- int newUser = 100;
- mTestSystemImpl.addUser(newUser);
- setEnabledAndValidPackageInfosForUser(newUser, packages);
- mWebViewUpdateServiceImpl.handleNewUser(newUser);
- if (fallbackLogicEnabled) {
- // Verify fallback package becomes disabled for new user
- Mockito.verify(mTestSystemImpl).enablePackageForUser(
- Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
- Mockito.eq(newUser));
- } else {
- // Verify that we don't disable fallback for new user
- Mockito.verify(mTestSystemImpl, Mockito.never()).enablePackageForUser(
- Mockito.anyObject(), Matchers.anyBoolean() /* enable */,
- Matchers.anyInt() /* user */);
- }
- }
-
/**
* Ensures that adding a new user for which the current WebView package is uninstalled causes a
* change of WebView provider.
@Test
public void testAddingNewUserWithUninstalledPackage() {
String primaryPackage = "primary";
- String fallbackPackage = "fallback";
+ String secondaryPackage = "secondary";
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo(
primaryPackage, "", true /* default available */, false /* fallback */, null),
new WebViewProviderInfo(
- fallbackPackage, "", true /* default available */, true /* fallback */, null)};
- setupWithPackages(packages, true /* fallbackLogicEnabled */);
+ secondaryPackage, "", true /* default available */, false /* fallback */,
+ null)};
+ setupWithPackages(packages);
setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
int newUser = 100;
mTestSystemImpl.addUser(newUser);
createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
false /* installed */));
mTestSystemImpl.setPackageInfoForUser(newUser,
- createPackageInfo(fallbackPackage, false /* enabled */, true /* valid */,
+ createPackageInfo(secondaryPackage, true /* enabled */, true /* valid */,
true /* installed */));
mWebViewUpdateServiceImpl.handleNewUser(newUser);
- // Verify fallback package doesn't become disabled for the primary user.
- Mockito.verify(mTestSystemImpl, Mockito.never()).enablePackageForUser(
- Mockito.anyObject(), Mockito.eq(false) /* enable */,
- Mockito.eq(TestSystemImpl.PRIMARY_USER_ID) /* user */);
- // Verify that we enable the fallback package for the secondary user.
- Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
- Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */,
- Mockito.eq(newUser) /* user */);
- checkPreparationPhasesForPackage(fallbackPackage, 1 /* numRelros */);
+ checkPreparationPhasesForPackage(secondaryPackage, 1 /* numRelros */);
}
/**
setupWithPackages(packages);
// Only 'install' nonChosenPackage
mTestSystemImpl.setPackageInfo(
- createPackageInfo(nonChosenPackage, true /* enabled */, true /* valid */, true /* installed */));
+ createPackageInfo(nonChosenPackage, true /* enabled */, true /* valid */,
+ true /* installed */));
// Set user-chosen package
mTestSystemImpl.updateUserSetting(null, chosenPackage);
checkPreparationPhasesForPackage(thirdPackage, 1);
mTestSystemImpl.setPackageInfo(
- createPackageInfo(secondPackage, true /* enabled */, false /* valid */, true /* installed */));
+ createPackageInfo(secondPackage, true /* enabled */, false /* valid */,
+ true /* installed */));
// Try to switch to the invalid second package, this should result in switching to the first
// package, since that is more preferred than the third one.
100000 /* candidate version */, false /* expected validity */);
}
- @Test
- public void testMinimumSystemVersionUsedFallbackIgnored() {
- checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */,
- 200000 /* candidate version */, false /* expected validity */, true /* add fallback */,
- 100000 /* fallback version */, false /* expected validity of fallback */);
- }
-
- @Test
- public void testFallbackValid() {
- checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */,
- 200000/* candidate version */, false /* expected validity */, true /* add fallback */,
- 300000 /* fallback version */, true /* expected validity of fallback */);
- }
-
- private void checkPackageVersions(int[] systemVersions, int candidateVersion,
- boolean candidateShouldBeValid) {
- checkPackageVersions(systemVersions, candidateVersion, candidateShouldBeValid,
- false, 0, false);
- }
-
/**
* Utility method for checking that package version restriction works as it should.
* I.e. that a package with lower version than the system-default is not valid and that a
* package with greater than or equal version code is considered valid.
*/
private void checkPackageVersions(int[] systemVersions, int candidateVersion,
- boolean candidateShouldBeValid, boolean addFallback, int fallbackVersion,
- boolean fallbackShouldBeValid) {
+ boolean candidateShouldBeValid) {
int numSystemPackages = systemVersions.length;
- int numFallbackPackages = (addFallback ? 1 : 0);
- int numPackages = systemVersions.length + 1 + numFallbackPackages;
+ int numPackages = systemVersions.length + 1;
String candidatePackage = "candidatePackage";
String systemPackage = "systemPackage";
- String fallbackPackage = "fallbackPackage";
// Each package needs a valid signature since we set isDebuggable to false
Signature signature = new Signature("11");
// Set up config
// 1. candidatePackage
- // 2-N. default available non-fallback packages
- // N+1. default available fallback package
+ // 2-N. default available packages
WebViewProviderInfo[] packages = new WebViewProviderInfo[numPackages];
packages[0] = new WebViewProviderInfo(candidatePackage, "",
false /* available by default */, false /* fallback */,
true /* available by default */, false /* fallback */,
new String[]{encodedSignatureString});
}
- if (addFallback) {
- packages[packages.length-1] = new WebViewProviderInfo(fallbackPackage, "",
- true /* available by default */, true /* fallback */,
- new String[]{encodedSignatureString});
- }
-
- setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
- false /* isDebuggable */);
+ setupWithPackagesNonDebuggable(packages);
// Set package infos
mTestSystemImpl.setPackageInfo(
true /* installed */, new Signature[]{signature}, 0 /* updateTime */,
false /* hidden */, systemVersions[n-1], true /* isSystemApp */));
}
- if (addFallback) {
- mTestSystemImpl.setPackageInfo(
- createPackageInfo(fallbackPackage, true /* enabled */, true /* valid */,
- true /* installed */, new Signature[]{signature}, 0 /* updateTime */,
- false /* hidden */, fallbackVersion, true /* isSystemApp */));
- }
WebViewProviderInfo[] validPackages = mWebViewUpdateServiceImpl.getValidWebViewPackages();
int expectedNumValidPackages = numSystemPackages;
}
}
- if (fallbackShouldBeValid) {
- expectedNumValidPackages += numFallbackPackages;
- } else {
- // Ensure the fallback package is not one of the valid packages
- for(int n = 0; n < validPackages.length; n++) {
- assertFalse(fallbackPackage.equals(validPackages[n].packageName));
- }
- }
-
assertEquals(expectedNumValidPackages, validPackages.length);
runWebViewBootPreparationOnMainSync();
WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
new WebViewProviderInfo(testPackageName, "",
true /*default available*/, false /* fallback */, null)};
- setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
+ setupWithPackages(webviewPackages);
mTestSystemImpl.setPackageInfo(createPackageInfo(testPackageName, true /* enabled */,
true /* valid */, false /* installed */));
new WebViewProviderInfo(installedPackage, "", true /* available by default */,
false /* fallback */, null)};
- setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
+ setupWithPackages(webviewPackages);
int secondaryUserId = 5;
if (multiUser) {
mTestSystemImpl.addUser(secondaryUserId);
new WebViewProviderInfo(installedPackage, "", true /* available by default */,
false /* fallback */, null)};
- setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
+ setupWithPackages(webviewPackages);
int secondaryUserId = 412;
mTestSystemImpl.addUser(secondaryUserId);
new WebViewProviderInfo(installedPackage, "", true /* available by default */,
false /* fallback */, null)};
- setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
+ setupWithPackages(webviewPackages);
int secondaryUserId = 4;
mTestSystemImpl.addUser(secondaryUserId);
}
@Test
- public void testFallbackEnabledIfPrimaryUninstalledSingleUser() {
- checkFallbackEnabledIfPrimaryUninstalled(false /* multiUser */);
- }
-
- @Test
- public void testFallbackEnabledIfPrimaryUninstalledMultiUser() {
- checkFallbackEnabledIfPrimaryUninstalled(true /* multiUser */);
- }
-
- /**
- * Ensures that fallback becomes enabled at boot if the primary package is uninstalled for some
- * user.
- */
- private void checkFallbackEnabledIfPrimaryUninstalled(boolean multiUser) {
- String primaryPackage = "primary";
- String fallbackPackage = "fallback";
- WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
- new WebViewProviderInfo(
- primaryPackage, "", true /* default available */, false /* fallback */, null),
- new WebViewProviderInfo(
- fallbackPackage, "", true /* default available */, true /* fallback */, null)};
- setupWithPackages(packages, true /* fallback logic enabled */);
- int secondaryUserId = 5;
- if (multiUser) {
- mTestSystemImpl.addUser(secondaryUserId);
- // Install all packages for the primary user.
- setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
- // Only install fallback package for secondary user.
- mTestSystemImpl.setPackageInfoForUser(secondaryUserId,
- createPackageInfo(primaryPackage, true /* enabled */,
- true /* valid */, false /* installed */));
- mTestSystemImpl.setPackageInfoForUser(secondaryUserId,
- createPackageInfo(fallbackPackage, false /* enabled */,
- true /* valid */, true /* installed */));
- } else {
- mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
- true /* valid */, false /* installed */));
- mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, false /* enabled */,
- true /* valid */, true /* installed */));
- }
-
- runWebViewBootPreparationOnMainSync();
- // Verify that we enable the fallback package
- Mockito.verify(mTestSystemImpl).enablePackageForAllUsers(
- Mockito.anyObject(), Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */);
-
- checkPreparationPhasesForPackage(fallbackPackage, 1 /* first preparation phase */);
- }
-
- @Test
public void testPreparationRunsIffNewPackage() {
String primaryPackage = "primary";
- String fallbackPackage = "fallback";
+ String secondaryPackage = "secondary";
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo(
primaryPackage, "", true /* default available */, false /* fallback */, null),
new WebViewProviderInfo(
- fallbackPackage, "", true /* default available */, true /* fallback */, null)};
- setupWithPackages(packages, true /* fallback logic enabled */);
+ secondaryPackage, "", true /* default available */, false /* fallback */,
+ null)};
+ setupWithPackages(packages);
mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
true /* valid */, true /* installed */, null /* signatures */,
10 /* lastUpdateTime*/ ));
- mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
+ mTestSystemImpl.setPackageInfo(createPackageInfo(secondaryPackage, true /* enabled */,
true /* valid */, true /* installed */));
runWebViewBootPreparationOnMainSync();
checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
- Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
- Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
- Matchers.anyInt() /* user */);
-
mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0 /* userId */);
// package still has the same update-time so we shouldn't run preparation here
Mockito.verify(mTestSystemImpl, Mockito.times(1)).onWebViewProviderChanged(
Mockito.argThat(new IsPackageInfoWithName(primaryPackage)));
- Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
- Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
- Matchers.anyInt() /* user */);
// Ensure we can still load the package
WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
firstPackage.versionName = "first package version";
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo(firstPackage.packageName, "", true, false, null)};
- setupWithPackages(packages, true);
+ setupWithPackages(packages);
mTestSystemImpl.setPackageInfo(firstPackage);
runWebViewBootPreparationOnMainSync();
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo(
primaryPackage, "", true /* default available */, false /* fallback */, null)};
- setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
- true /* debuggable */,
- enabledByDefault /* not multiprocess by default */);
+ setupWithPackagesAndMultiProcess(packages, enabledByDefault);
mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
true /* valid */, true /* installed */, null /* signatures */,
10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo(
primaryPackage, "", true /* default available */, false /* fallback */, null)};
- setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
- true /* debuggable */, enabledByDefault /* multiprocess by default */);
+ setupWithPackagesAndMultiProcess(packages, enabledByDefault);
mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
true /* valid */, true /* installed */, null /* signatures */,
10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo(oldSdkPackage.packageName, "", true, false, null),
currentSdkProviderInfo, newSdkProviderInfo};
- setupWithPackages(packages, true);
+ setupWithPackages(packages);
;
mTestSystemImpl.setPackageInfo(newSdkPackage);
mTestSystemImpl.setPackageInfo(currentSdkPackage);