Fix WebViewUpdateServiceTest failures when using Thread without Looper.

Add some more methods to SystemInterface to avoid calling into the rest
of the framework from WebViewUpdateServiceTests.

Also convert WebViewUpdateServiceTest to use non-deprecated test
utilities.

Test: make sure tests in WebViewUpdateServiceTest pass.
Bug: 32364900
Change-Id: I8cf67568bb7e551e1c011028e0bb4e15c0e9f2bb
This commit is contained in:
Gustav Sennton
2016-10-24 16:49:32 +01:00
committed by Torne (Richard Coles)
parent d19524f4f2
commit 86f7bbe134
5 changed files with 110 additions and 51 deletions

View File

@@ -26,6 +26,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
import android.os.Build;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -270,8 +271,21 @@ public class SystemImpl implements SystemInterface {
}
@Override
public void setMultiprocessEnabled(boolean enabled) {
WebViewZygote.setMultiprocessEnabled(enabled);
public void setMultiProcessEnabledFromContext(Context context) {
boolean enableMultiProcess = false;
try {
enableMultiProcess = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.WEBVIEW_MULTIPROCESS) == 1;
} catch (Settings.SettingNotFoundException ex) {
}
WebViewZygote.setMultiprocessEnabled(enableMultiProcess);
}
@Override
public void registerContentObserver(Context context, ContentObserver contentObserver) {
context.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.WEBVIEW_MULTIPROCESS),
false, contentObserver);
}
// flags declaring we want extra info from the package manager for webview providers

View File

@@ -19,6 +19,7 @@ package com.android.server.webkit;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.ContentObserver;
import android.webkit.WebViewProviderInfo;
/**
@@ -49,5 +50,6 @@ public interface SystemInterface {
public PackageInfo getPackageInfoForProvider(WebViewProviderInfo configInfo)
throws NameNotFoundException;
public void setMultiprocessEnabled(boolean enabled);
public void setMultiProcessEnabledFromContext(Context context);
public void registerContentObserver(Context context, ContentObserver contentObserver);
}

View File

@@ -20,12 +20,10 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Base64;
import android.util.Slog;
import android.webkit.WebViewFactory;
@@ -48,7 +46,7 @@ public class WebViewUpdateServiceImpl {
private SystemInterface mSystemInterface;
private WebViewUpdater mWebViewUpdater;
private SettingsObserver mSettingsObserver;
private Context mContext;
final private Context mContext;
public WebViewUpdateServiceImpl(Context context, SystemInterface systemInterface) {
mContext = context;
@@ -683,15 +681,10 @@ public class WebViewUpdateServiceImpl {
* appropriately.
*/
private class SettingsObserver extends ContentObserver {
private final ContentResolver mResolver;
SettingsObserver() {
super(new Handler());
mResolver = mContext.getContentResolver();
mResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.WEBVIEW_MULTIPROCESS),
false, this);
mSystemInterface.registerContentObserver(mContext, this);
// Push the current value of the setting immediately.
notifyZygote();
@@ -703,15 +696,7 @@ public class WebViewUpdateServiceImpl {
}
private void notifyZygote() {
boolean enableMultiprocess = false;
try {
enableMultiprocess = Settings.Global.getInt(mResolver,
Settings.Global.WEBVIEW_MULTIPROCESS) == 1;
} catch (Settings.SettingNotFoundException ex) {
}
mSystemInterface.setMultiprocessEnabled(enableMultiprocess);
mSystemInterface.setMultiProcessEnabledFromContext(mContext);
}
}
}

View File

@@ -19,6 +19,7 @@ package com.android.server.webkit;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.ContentObserver;
import android.webkit.WebViewProviderInfo;
import java.util.HashMap;
@@ -115,5 +116,8 @@ public class TestSystemImpl implements SystemInterface {
}
@Override
public void setMultiprocessEnabled(boolean enabled) {}
public void setMultiProcessEnabledFromContext(Context context) {}
@Override
public void registerContentObserver(Context context, ContentObserver contentObserver) {}
}

View File

@@ -16,31 +16,42 @@
package com.android.server.webkit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.Signature;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Base64;
import android.test.AndroidTestCase;
import android.webkit.WebViewFactory;
import android.webkit.WebViewProviderInfo;
import android.webkit.WebViewProviderResponse;
import java.util.concurrent.CountDownLatch;
import org.hamcrest.Description;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.Matchers;
import org.mockito.ArgumentMatcher;
import java.util.concurrent.CountDownLatch;
/**
* Tests for WebViewUpdateService
*/
public class WebViewUpdateServiceTest extends AndroidTestCase {
// Use MediumTest instead of SmallTest as the implementation of WebViewUpdateService
// is intended to work on several threads and uses at least one sleep/wait-statement.
@RunWith(AndroidJUnit4.class)
@MediumTest
public class WebViewUpdateServiceTest {
private final static String TAG = WebViewUpdateServiceTest.class.getSimpleName();
private WebViewUpdateServiceImpl mWebViewUpdateServiceImpl;
@@ -48,11 +59,6 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
private static final String WEBVIEW_LIBRARY_FLAG = "com.android.webview.WebViewLibrary";
@Override
protected void setUp() throws Exception {
super.setUp();
}
/**
* Creates a new instance.
*/
@@ -102,7 +108,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
// Add (enabled and valid) package infos for each provider
setEnabledAndValidPackageInfos(webviewPackages);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
Mockito.argThat(new IsPackageInfoWithName(expectedProviderName)));
@@ -188,12 +194,27 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
assertEquals(expectedPackage, response.packageInfo.packageName);
}
/**
* The WebView preparation boot phase is run on the main thread (especially on a thread with a
* looper) so to avoid bugs where our tests fail because a looper hasn't been attached to the
* thread running prepareWebViewInSystemServer we run it on the main thread.
*/
private void runWebViewBootPreparationOnMainSync() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
}
});
}
// ****************
// Tests
// ****************
@Test
public void testWithSinglePackage() {
String testPackageName = "test.package.name";
checkCertainPackageUsedAfterWebViewBootPreparation(testPackageName,
@@ -202,6 +223,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
true /*default available*/, false /* fallback */, null)});
}
@Test
public void testDefaultPackageUsedOverNonDefault() {
String defaultPackage = "defaultPackage";
String nonDefaultPackage = "nonDefaultPackage";
@@ -211,6 +233,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
checkCertainPackageUsedAfterWebViewBootPreparation(defaultPackage, packages);
}
@Test
public void testSeveralRelros() {
String singlePackage = "singlePackage";
checkCertainPackageUsedAfterWebViewBootPreparation(
@@ -222,6 +245,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
// Ensure that package with valid signatures is chosen rather than package with invalid
// signatures.
@Test
public void testWithSignatures() {
String validPackage = "valid package";
String invalidPackage = "invalid package";
@@ -247,7 +271,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
true /* valid */, true /* installed */, new Signature[]{validSignature}
, 0 /* updateTime */));
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
checkPreparationPhasesForPackage(validPackage, 1 /* first preparation for this package */);
@@ -257,13 +281,14 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
assertEquals(validPackage, validPackages[0].packageName);
}
@Test
public void testFailWaitingForRelro() {
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
new WebViewProviderInfo("packagename", "", true, true, null)};
setupWithPackages(packages);
setEnabledAndValidPackageInfos(packages);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
Mockito.argThat(new IsPackageInfoWithName(packages[0].packageName)));
@@ -274,12 +299,13 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
assertEquals(WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO, response.status);
}
@Test
public void testFailListingEmptyWebviewPackages() {
WebViewProviderInfo[] packages = new WebViewProviderInfo[0];
setupWithPackages(packages);
setEnabledAndValidPackageInfos(packages);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
Matchers.anyObject());
@@ -288,6 +314,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
}
@Test
public void testFailListingInvalidWebviewPackage() {
WebViewProviderInfo wpi = new WebViewProviderInfo("package", "", true, true, null);
WebViewProviderInfo[] packages = new WebViewProviderInfo[] {wpi};
@@ -296,7 +323,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
createPackageInfo(wpi.packageName, true /* enabled */, false /* valid */,
true /* installed */));
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
Matchers.anyObject());
@@ -315,6 +342,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
}
// Test that switching provider using changeProviderAndSetting works.
@Test
public void testSwitchingProvider() {
String firstPackage = "first";
String secondPackage = "second";
@@ -324,6 +352,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
checkSwitchingProvider(packages, firstPackage, secondPackage);
}
@Test
public void testSwitchingProviderToNonDefault() {
String defaultPackage = "defaultPackage";
String nonDefaultPackage = "nonDefaultPackage";
@@ -344,11 +373,13 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
}
// Change provider during relro creation by using changeProviderAndSetting
@Test
public void testSwitchingProviderDuringRelroCreation() {
checkChangingProviderDuringRelroCreation(true);
}
// Change provider during relro creation by enabling a provider
@Test
public void testChangingProviderThroughEnablingDuringRelroCreation() {
checkChangingProviderDuringRelroCreation(false);
}
@@ -373,7 +404,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
CountDownLatch countdown = new CountDownLatch(1);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
Mockito.argThat(new IsPackageInfoWithName(firstPackage)));
@@ -420,10 +451,12 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
}
}
@Test
public void testRunFallbackLogicIfEnabled() {
checkFallbackLogicBeingRun(true);
}
@Test
public void testDontRunFallbackLogicIfDisabled() {
checkFallbackLogicBeingRun(false);
}
@@ -439,7 +472,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
setupWithPackages(packages, fallbackLogicEnabled);
setEnabledAndValidPackageInfos(packages);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
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) {
@@ -475,6 +508,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
* 2. Install non-fallback
* 3. Fallback should be disabled
*/
@Test
public void testInstallingNonFallbackPackage() {
String primaryPackage = "primary";
String fallbackPackage = "fallback";
@@ -488,7 +522,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
createPackageInfo(fallbackPackage, true /* enabled */ , true /* valid */,
true /* installed */));
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
Matchers.anyObject(), Matchers.anyObject());
@@ -509,6 +543,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(fallbackPackage));
}
@Test
public void testFallbackChangesEnabledState() {
String primaryPackage = "primary";
String fallbackPackage = "fallback";
@@ -520,7 +555,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
setupWithPackages(packages, true /* fallbackLogicEnabled */);
setEnabledAndValidPackageInfos(packages);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
// Verify fallback disabled at boot when primary package enabled
Mockito.verify(mTestSystemImpl).enablePackageForUser(
@@ -558,10 +593,12 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
checkPreparationPhasesForPackage(primaryPackage, 2);
}
@Test
public void testAddUserWhenFallbackLogicEnabled() {
checkAddingNewUser(true);
}
@Test
public void testAddUserWhenFallbackLogicDisabled() {
checkAddingNewUser(false);
}
@@ -595,6 +632,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
* Timing dependent test where we verify that the list of valid webview packages becoming empty
* at a certain point doesn't crash us or break our state.
*/
@Test
public void testNotifyRelroDoesntCrashIfNoPackages() {
String firstPackage = "first";
String secondPackage = "second";
@@ -607,7 +645,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
// Add (enabled and valid) package infos for each provider
setEnabledAndValidPackageInfos(packages);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
Mockito.argThat(new IsPackageInfoWithName(firstPackage)));
@@ -646,6 +684,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
* Verify that even if a user-chosen package is removed temporarily we start using it again when
* it is added back.
*/
@Test
public void testTempRemovePackageDoesntSwitchProviderPermanently() {
String firstPackage = "first";
String secondPackage = "second";
@@ -679,6 +718,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
* Ensure that we update the user-chosen setting across boots if the chosen package is no
* longer installed and valid.
*/
@Test
public void testProviderSettingChangedDuringBootIfProviderNotAvailable() {
String chosenPackage = "chosenPackage";
String nonChosenPackage = "non-chosenPackage";
@@ -696,7 +736,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
// Set user-chosen package
mTestSystemImpl.updateUserSetting(null, chosenPackage);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
// Verify that we switch the setting to point to the current package
Mockito.verify(mTestSystemImpl).updateUserSetting(
@@ -706,10 +746,12 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
checkPreparationPhasesForPackage(nonChosenPackage, 1);
}
@Test
public void testRecoverFailedListingWebViewPackagesSettingsChange() {
checkRecoverAfterFailListingWebviewPackages(true);
}
@Test
public void testRecoverFailedListingWebViewPackagesAddedPackage() {
checkRecoverAfterFailListingWebviewPackages(false);
}
@@ -756,10 +798,12 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
checkPreparationPhasesForPackage(secondPackage, 1);
}
@Test
public void testDontKillIfPackageReplaced() {
checkDontKillIfPackageRemoved(true);
}
@Test
public void testDontKillIfPackageRemoved() {
checkDontKillIfPackageRemoved(false);
}
@@ -793,6 +837,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
Mockito.anyObject());
}
@Test
public void testKillIfSettingChanged() {
String firstPackage = "first";
String secondPackage = "second";
@@ -814,6 +859,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
* Test that we kill apps using an old provider when we change the provider setting, even if the
* new provider is not the one we intended to change to.
*/
@Test
public void testKillIfChangeProviderIncorrectly() {
String firstPackage = "first";
String secondPackage = "second";
@@ -831,7 +877,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
// Start with the setting pointing to the third package
mTestSystemImpl.updateUserSetting(null, thirdPackage);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
checkPreparationPhasesForPackage(thirdPackage, 1);
mTestSystemImpl.setPackageInfo(
@@ -849,6 +895,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
// Ensure that the update service uses an uninstalled package if that is the only package
// available.
@Test
public void testWithSingleUninstalledPackage() {
String testPackageName = "test.package.name";
WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
@@ -858,15 +905,17 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
mTestSystemImpl.setPackageInfo(createPackageInfo(testPackageName, true /* enabled */,
true /* valid */, false /* installed */));
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
checkPreparationPhasesForPackage(testPackageName, 1 /* first preparation phase */);
}
@Test
public void testNonhiddenPackageUserOverHidden() {
checkVisiblePackageUserOverNonVisible(false /* true == uninstalled, false == hidden */);
}
@Test
public void testInstalledPackageUsedOverUninstalled() {
checkVisiblePackageUserOverNonVisible(true /* true == uninstalled, false == hidden */);
}
@@ -889,16 +938,18 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
true /* valid */, (testUninstalled ? false : true) /* installed */,
null /* signatures */, 0 /* updateTime */, (testHidden ? true : false)));
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
}
@Test
public void testCantSwitchToHiddenPackage () {
checkCantSwitchToNonVisiblePackage(false /* true == uninstalled, false == hidden */);
}
@Test
public void testCantSwitchToUninstalledPackage () {
checkCantSwitchToNonVisiblePackage(true /* true == uninstalled, false == hidden */);
}
@@ -927,7 +978,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
null /* signatures */, 0 /* updateTime */,
(testHidden ? true : false) /* hidden */));
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
@@ -947,11 +998,13 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
Mockito.argThat(new IsPackageInfoWithName(installedPackage)));
}
@Test
public void testHiddenPackageNotPrioritizedEvenIfChosen() {
checkNonvisiblePackageNotPrioritizedEvenIfChosen(
false /* true == uninstalled, false == hidden */);
}
@Test
public void testUninstalledPackageNotPrioritizedEvenIfChosen() {
checkNonvisiblePackageNotPrioritizedEvenIfChosen(
true /* true == uninstalled, false == hidden */);
@@ -979,7 +1032,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
// Start with the setting pointing to the uninstalled package
mTestSystemImpl.updateUserSetting(null, uninstalledPackage);
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
}
@@ -988,6 +1041,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
* Ensures that fallback becomes enabled if the primary package is uninstalled for the current
* user.
*/
@Test
public void testFallbackEnabledIfPrimaryUninstalled() {
String primaryPackage = "primary";
String fallbackPackage = "fallback";
@@ -1002,7 +1056,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
true /* valid */, true /* installed */));
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
// Verify that we enable the fallback package
Mockito.verify(mTestSystemImpl).enablePackageForAllUsers(
Mockito.anyObject(), Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */);
@@ -1010,6 +1064,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
checkPreparationPhasesForPackage(fallbackPackage, 1 /* first preparation phase */);
}
@Test
public void testPreparationRunsIffNewPackage() {
String primaryPackage = "primary";
String fallbackPackage = "fallback";
@@ -1025,7 +1080,7 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
true /* valid */, true /* installed */));
mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
runWebViewBootPreparationOnMainSync();
checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
@@ -1070,5 +1125,4 @@ public class WebViewUpdateServiceTest extends AndroidTestCase {
checkPreparationPhasesForPackage(primaryPackage, 3 /* third preparation phase */);
}
}