blob: 2e60866b9a5be1eeb95088deda74b706bc380583 [file] [log] [blame]
Gustav Sennton53b78242016-04-07 15:56:10 +01001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.webkit;
18
Gustav Sennton564c2fd2017-01-30 18:08:01 +000019import static org.junit.Assert.assertArrayEquals;
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010020import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertFalse;
22
Gustav Sennton53b78242016-04-07 15:56:10 +010023import android.content.pm.ApplicationInfo;
24import android.content.pm.PackageInfo;
25import android.content.pm.Signature;
Gustav Sennton564c2fd2017-01-30 18:08:01 +000026import android.os.Build;
Gustav Sennton53b78242016-04-07 15:56:10 +010027import android.os.Bundle;
Gustav Sennton148cb3e2016-09-02 15:58:38 +010028import android.test.suitebuilder.annotation.MediumTest;
Gustav Sennton53b78242016-04-07 15:56:10 +010029import android.util.Base64;
Gustav Senntone5468f72017-11-20 19:42:43 +000030import android.webkit.UserPackage;
Gustav Sennton53b78242016-04-07 15:56:10 +010031import android.webkit.WebViewFactory;
32import android.webkit.WebViewProviderInfo;
33import android.webkit.WebViewProviderResponse;
34
Brett Chabota26eda92018-07-23 13:08:30 -070035import androidx.test.InstrumentationRegistry;
36import androidx.test.runner.AndroidJUnit4;
37
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010038import org.junit.Test;
39import org.junit.runner.RunWith;
Philip P. Moltmann68366072017-11-27 12:29:20 -080040import org.mockito.ArgumentMatcher;
Gustav Sennton53b78242016-04-07 15:56:10 +010041import org.mockito.Matchers;
Brett Chabota26eda92018-07-23 13:08:30 -070042import org.mockito.Mockito;
Gustav Sennton53b78242016-04-07 15:56:10 +010043
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010044import java.util.concurrent.CountDownLatch;
45
Gustav Sennton53b78242016-04-07 15:56:10 +010046/**
47 * Tests for WebViewUpdateService
Gustav Sennton148cb3e2016-09-02 15:58:38 +010048 runtest --path frameworks/base/services/tests/servicestests/ \
49 -c com.android.server.webkit.WebViewUpdateServiceTest
Gustav Sennton53b78242016-04-07 15:56:10 +010050 */
Gustav Sennton148cb3e2016-09-02 15:58:38 +010051// Use MediumTest instead of SmallTest as the implementation of WebViewUpdateService
52// is intended to work on several threads and uses at least one sleep/wait-statement.
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010053@RunWith(AndroidJUnit4.class)
Gustav Sennton148cb3e2016-09-02 15:58:38 +010054@MediumTest
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010055public class WebViewUpdateServiceTest {
Gustav Sennton53b78242016-04-07 15:56:10 +010056 private final static String TAG = WebViewUpdateServiceTest.class.getSimpleName();
57
58 private WebViewUpdateServiceImpl mWebViewUpdateServiceImpl;
59 private TestSystemImpl mTestSystemImpl;
60
61 private static final String WEBVIEW_LIBRARY_FLAG = "com.android.webview.WebViewLibrary";
62
Gustav Sennton53b78242016-04-07 15:56:10 +010063 /**
64 * Creates a new instance.
65 */
66 public WebViewUpdateServiceTest() {
67 }
68
69 private void setupWithPackages(WebViewProviderInfo[] packages) {
Torne (Richard Coles)ef478902019-03-28 15:03:21 -040070 setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */,
71 true /* isDebuggable */, false /* multiProcessDefault */);
Gustav Sennton53b78242016-04-07 15:56:10 +010072 }
73
Torne (Richard Coles)ef478902019-03-28 15:03:21 -040074 private void setupWithPackagesAndFallbackLogic(WebViewProviderInfo[] packages) {
75 setupWithAllParameters(packages, true /* fallbackLogicEnabled */, 1 /* numRelros */,
76 true /* isDebuggable */, false /* multiProcessDefault */);
Gustav Sennton53b78242016-04-07 15:56:10 +010077 }
78
Torne (Richard Coles)ef478902019-03-28 15:03:21 -040079 private void setupWithPackagesAndRelroCount(WebViewProviderInfo[] packages, int numRelros) {
80 setupWithAllParameters(packages, false /* fallbackLogicEnabled */, numRelros,
81 true /* isDebuggable */, false /* multiProcessDefault */);
Gustav Sennton53b78242016-04-07 15:56:10 +010082 }
83
Torne (Richard Coles)ef478902019-03-28 15:03:21 -040084 private void setupWithPackagesNonDebuggable(WebViewProviderInfo[] packages) {
85 setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */,
86 false /* isDebuggable */, false /* multiProcessDefault */);
Torne (Richard Coles)dc375072017-01-11 15:48:13 +000087 }
88
Torne (Richard Coles)ef478902019-03-28 15:03:21 -040089 private void setupWithPackagesAndMultiProcess(WebViewProviderInfo[] packages,
90 boolean multiProcessDefault) {
91 setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */,
92 true /* isDebuggable */, multiProcessDefault);
93 }
94
95 private void setupWithAllParameters(WebViewProviderInfo[] packages,
Torne (Richard Coles)dc375072017-01-11 15:48:13 +000096 boolean fallbackLogicEnabled, int numRelros, boolean isDebuggable,
97 boolean multiProcessDefault) {
Gustav Sennton53b78242016-04-07 15:56:10 +010098 TestSystemImpl testing = new TestSystemImpl(packages, fallbackLogicEnabled, numRelros,
Torne (Richard Coles)dc375072017-01-11 15:48:13 +000099 isDebuggable, multiProcessDefault);
Gustav Sennton53b78242016-04-07 15:56:10 +0100100 mTestSystemImpl = Mockito.spy(testing);
101 mWebViewUpdateServiceImpl =
102 new WebViewUpdateServiceImpl(null /*Context*/, mTestSystemImpl);
103 }
104
105 private void setEnabledAndValidPackageInfos(WebViewProviderInfo[] providers) {
Gustav Sennton364e1602016-12-14 09:10:50 +0000106 // Set package infos for the primary user (user 0).
107 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, providers);
108 }
109
110 private void setEnabledAndValidPackageInfosForUser(int userId,
111 WebViewProviderInfo[] providers) {
Gustav Sennton53b78242016-04-07 15:56:10 +0100112 for(WebViewProviderInfo wpi : providers) {
Gustav Sennton364e1602016-12-14 09:10:50 +0000113 mTestSystemImpl.setPackageInfoForUser(userId, createPackageInfo(wpi.packageName,
114 true /* enabled */, true /* valid */, true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100115 }
116 }
117
Gustav Senntona9159042016-04-11 16:32:52 +0100118 private void checkCertainPackageUsedAfterWebViewBootPreparation(String expectedProviderName,
Gustav Sennton53b78242016-04-07 15:56:10 +0100119 WebViewProviderInfo[] webviewPackages) {
Gustav Senntona9159042016-04-11 16:32:52 +0100120 checkCertainPackageUsedAfterWebViewBootPreparation(
121 expectedProviderName, webviewPackages, 1);
Gustav Sennton53b78242016-04-07 15:56:10 +0100122 }
123
Gustav Senntona9159042016-04-11 16:32:52 +0100124 private void checkCertainPackageUsedAfterWebViewBootPreparation(String expectedProviderName,
Gustav Sennton53b78242016-04-07 15:56:10 +0100125 WebViewProviderInfo[] webviewPackages, int numRelros) {
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400126 setupWithPackagesAndRelroCount(webviewPackages, numRelros);
Gustav Sennton53b78242016-04-07 15:56:10 +0100127 // Add (enabled and valid) package infos for each provider
128 setEnabledAndValidPackageInfos(webviewPackages);
129
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100130 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100131
132 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
133 Mockito.argThat(new IsPackageInfoWithName(expectedProviderName)));
134
135 for (int n = 0; n < numRelros; n++) {
136 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
137 }
138
139 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
140 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, response.status);
141 assertEquals(expectedProviderName, response.packageInfo.packageName);
142 }
143
144 // For matching the package name of a PackageInfo
Philip P. Moltmann68366072017-11-27 12:29:20 -0800145 private class IsPackageInfoWithName implements ArgumentMatcher<PackageInfo> {
Gustav Sennton53b78242016-04-07 15:56:10 +0100146 private final String mPackageName;
147
148 IsPackageInfoWithName(String name) {
149 mPackageName = name;
150 }
151
152 @Override
Philip P. Moltmann68366072017-11-27 12:29:20 -0800153 public boolean matches(PackageInfo p) {
154 return p.packageName.equals(mPackageName);
Gustav Sennton53b78242016-04-07 15:56:10 +0100155 }
156
Gustav Sennton53b78242016-04-07 15:56:10 +0100157 @Override
Paul Duffin192bb0b2017-03-09 18:49:41 +0000158 public String toString() {
159 return String.format("PackageInfo with name '%s'", mPackageName);
Gustav Sennton53b78242016-04-07 15:56:10 +0100160 }
161 }
162
163 private static PackageInfo createPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100164 String packageName, boolean enabled, boolean valid, boolean installed) {
Gustav Sennton53b78242016-04-07 15:56:10 +0100165 PackageInfo p = new PackageInfo();
166 p.packageName = packageName;
167 p.applicationInfo = new ApplicationInfo();
168 p.applicationInfo.enabled = enabled;
169 p.applicationInfo.metaData = new Bundle();
Gustav Sennton0df2c552016-06-14 15:32:19 +0100170 if (installed) {
171 p.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
172 } else {
173 p.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
174 }
Gustav Sennton53b78242016-04-07 15:56:10 +0100175 if (valid) {
176 // no flag means invalid
177 p.applicationInfo.metaData.putString(WEBVIEW_LIBRARY_FLAG, "blah");
178 }
Gustav Sennton564c2fd2017-01-30 18:08:01 +0000179 // Default to this package being valid in terms of targetSdkVersion.
180 p.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
Gustav Sennton53b78242016-04-07 15:56:10 +0100181 return p;
182 }
183
Gustav Sennton0df2c552016-06-14 15:32:19 +0100184 private static PackageInfo createPackageInfo(String packageName, boolean enabled, boolean valid,
185 boolean installed, Signature[] signatures, long updateTime) {
186 PackageInfo p = createPackageInfo(packageName, enabled, valid, installed);
Gustav Sennton53b78242016-04-07 15:56:10 +0100187 p.signatures = signatures;
Gustav Sennton0df2c552016-06-14 15:32:19 +0100188 p.lastUpdateTime = updateTime;
Gustav Sennton53b78242016-04-07 15:56:10 +0100189 return p;
190 }
191
Gustav Sennton18c9e152016-04-15 15:24:53 +0100192 private static PackageInfo createPackageInfo(String packageName, boolean enabled, boolean valid,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100193 boolean installed, Signature[] signatures, long updateTime, boolean hidden) {
194 PackageInfo p =
195 createPackageInfo(packageName, enabled, valid, installed, signatures, updateTime);
196 if (hidden) {
197 p.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
198 } else {
199 p.applicationInfo.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_HIDDEN;
200 }
Gustav Sennton53b78242016-04-07 15:56:10 +0100201 return p;
202 }
203
Gustav Senntonfd222fc22016-06-16 20:24:23 +0100204 private static PackageInfo createPackageInfo(String packageName, boolean enabled, boolean valid,
205 boolean installed, Signature[] signatures, long updateTime, boolean hidden,
Dianne Hackborn891b74c2017-12-11 16:54:27 -0800206 long versionCode, boolean isSystemApp) {
Gustav Senntonfd222fc22016-06-16 20:24:23 +0100207 PackageInfo p = createPackageInfo(packageName, enabled, valid, installed, signatures,
208 updateTime, hidden);
Dianne Hackborn891b74c2017-12-11 16:54:27 -0800209 p.setLongVersionCode(versionCode);
Patrick Baumannc2def582018-04-04 12:14:15 -0700210 p.applicationInfo.setVersionCode(versionCode);
Gustav Sennton18c9e152016-04-15 15:24:53 +0100211 if (isSystemApp) p.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
212 return p;
213 }
214
Gustav Senntona9159042016-04-11 16:32:52 +0100215 private void checkPreparationPhasesForPackage(String expectedPackage, int numPreparation) {
216 // Verify that onWebViewProviderChanged was called for the numPreparation'th time for the
217 // expected package
218 Mockito.verify(mTestSystemImpl, Mockito.times(numPreparation)).onWebViewProviderChanged(
219 Mockito.argThat(new IsPackageInfoWithName(expectedPackage)));
220
221 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
222
223 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
224 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, response.status);
225 assertEquals(expectedPackage, response.packageInfo.packageName);
226 }
227
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100228 /**
229 * The WebView preparation boot phase is run on the main thread (especially on a thread with a
230 * looper) so to avoid bugs where our tests fail because a looper hasn't been attached to the
231 * thread running prepareWebViewInSystemServer we run it on the main thread.
232 */
233 private void runWebViewBootPreparationOnMainSync() {
234 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
235 @Override
236 public void run() {
237 mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
238 }
239 });
240 }
241
Gustav Sennton53b78242016-04-07 15:56:10 +0100242
243 // ****************
244 // Tests
245 // ****************
246
247
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100248 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100249 public void testWithSinglePackage() {
250 String testPackageName = "test.package.name";
Gustav Senntona9159042016-04-11 16:32:52 +0100251 checkCertainPackageUsedAfterWebViewBootPreparation(testPackageName,
Gustav Sennton53b78242016-04-07 15:56:10 +0100252 new WebViewProviderInfo[] {
253 new WebViewProviderInfo(testPackageName, "",
254 true /*default available*/, false /* fallback */, null)});
255 }
256
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100257 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100258 public void testDefaultPackageUsedOverNonDefault() {
259 String defaultPackage = "defaultPackage";
260 String nonDefaultPackage = "nonDefaultPackage";
261 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
262 new WebViewProviderInfo(nonDefaultPackage, "", false, false, null),
263 new WebViewProviderInfo(defaultPackage, "", true, false, null)};
Gustav Senntona9159042016-04-11 16:32:52 +0100264 checkCertainPackageUsedAfterWebViewBootPreparation(defaultPackage, packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100265 }
266
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100267 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100268 public void testSeveralRelros() {
269 String singlePackage = "singlePackage";
Gustav Senntona9159042016-04-11 16:32:52 +0100270 checkCertainPackageUsedAfterWebViewBootPreparation(
Gustav Sennton53b78242016-04-07 15:56:10 +0100271 singlePackage,
272 new WebViewProviderInfo[] {
273 new WebViewProviderInfo(singlePackage, "", true /*def av*/, false, null)},
274 2);
275 }
276
277 // Ensure that package with valid signatures is chosen rather than package with invalid
278 // signatures.
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100279 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100280 public void testWithSignatures() {
281 String validPackage = "valid package";
282 String invalidPackage = "invalid package";
283
284 Signature validSignature = new Signature("11");
285 Signature invalidExpectedSignature = new Signature("22");
286 Signature invalidPackageSignature = new Signature("33");
287
288 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
289 new WebViewProviderInfo(invalidPackage, "", true, false, new String[]{
290 Base64.encodeToString(
291 invalidExpectedSignature.toByteArray(), Base64.DEFAULT)}),
292 new WebViewProviderInfo(validPackage, "", true, false, new String[]{
293 Base64.encodeToString(
294 validSignature.toByteArray(), Base64.DEFAULT)})
295 };
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400296 setupWithPackagesNonDebuggable(packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100297 mTestSystemImpl.setPackageInfo(createPackageInfo(invalidPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100298 true /* valid */, true /* installed */, new Signature[]{invalidPackageSignature}
299 , 0 /* updateTime */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100300 mTestSystemImpl.setPackageInfo(createPackageInfo(validPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100301 true /* valid */, true /* installed */, new Signature[]{validSignature}
302 , 0 /* updateTime */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100303
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100304 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100305
Gustav Sennton53b78242016-04-07 15:56:10 +0100306
Gustav Senntona9159042016-04-11 16:32:52 +0100307 checkPreparationPhasesForPackage(validPackage, 1 /* first preparation for this package */);
Gustav Sennton53b78242016-04-07 15:56:10 +0100308
309 WebViewProviderInfo[] validPackages = mWebViewUpdateServiceImpl.getValidWebViewPackages();
310 assertEquals(1, validPackages.length);
311 assertEquals(validPackage, validPackages[0].packageName);
312 }
313
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100314 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100315 public void testFailWaitingForRelro() {
316 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
317 new WebViewProviderInfo("packagename", "", true, true, null)};
318 setupWithPackages(packages);
319 setEnabledAndValidPackageInfos(packages);
320
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100321 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100322
323 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
324 Mockito.argThat(new IsPackageInfoWithName(packages[0].packageName)));
325
326 // Never call notifyRelroCreation()
327
328 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
329 assertEquals(WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO, response.status);
330 }
331
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100332 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100333 public void testFailListingEmptyWebviewPackages() {
334 WebViewProviderInfo[] packages = new WebViewProviderInfo[0];
335 setupWithPackages(packages);
336 setEnabledAndValidPackageInfos(packages);
337
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100338 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100339
340 Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
341 Matchers.anyObject());
342
343 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
344 assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
Gustav Senntonbf683e02016-09-15 14:42:50 +0100345 assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage());
346
347 // Now install a package
348 String singlePackage = "singlePackage";
349 packages = new WebViewProviderInfo[]{
350 new WebViewProviderInfo(singlePackage, "", true, false, null)};
351 setupWithPackages(packages);
352 setEnabledAndValidPackageInfos(packages);
353
354 mWebViewUpdateServiceImpl.packageStateChanged(singlePackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000355 WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Senntonbf683e02016-09-15 14:42:50 +0100356
357 checkPreparationPhasesForPackage(singlePackage, 1 /* number of finished preparations */);
358 assertEquals(singlePackage,
359 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
360
361 // Remove the package again
362 mTestSystemImpl.removePackageInfo(singlePackage);
363 mWebViewUpdateServiceImpl.packageStateChanged(singlePackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000364 WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Senntonbf683e02016-09-15 14:42:50 +0100365
366 // Package removed - ensure our interface states that there is no package
367 response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
368 assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
369 assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage());
Gustav Sennton53b78242016-04-07 15:56:10 +0100370 }
371
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100372 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100373 public void testFailListingInvalidWebviewPackage() {
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100374 WebViewProviderInfo wpi = new WebViewProviderInfo("package", "", true, true, null);
Gustav Sennton53b78242016-04-07 15:56:10 +0100375 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {wpi};
376 setupWithPackages(packages);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100377 mTestSystemImpl.setPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100378 createPackageInfo(wpi.packageName, true /* enabled */, false /* valid */,
379 true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100380
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100381 runWebViewBootPreparationOnMainSync();
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100382
383 Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
384 Matchers.anyObject());
385
Gustav Sennton53b78242016-04-07 15:56:10 +0100386 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
387 assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100388
389 // Verify that we can recover from failing to list webview packages.
390 mTestSystemImpl.setPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100391 createPackageInfo(wpi.packageName, true /* enabled */, true /* valid */,
392 true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100393 mWebViewUpdateServiceImpl.packageStateChanged(wpi.packageName,
Gustav Sennton364e1602016-12-14 09:10:50 +0000394 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100395
396 checkPreparationPhasesForPackage(wpi.packageName, 1);
Gustav Sennton53b78242016-04-07 15:56:10 +0100397 }
398
399 // Test that switching provider using changeProviderAndSetting works.
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100400 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100401 public void testSwitchingProvider() {
402 String firstPackage = "first";
403 String secondPackage = "second";
404 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
405 new WebViewProviderInfo(firstPackage, "", true, false, null),
406 new WebViewProviderInfo(secondPackage, "", true, false, null)};
407 checkSwitchingProvider(packages, firstPackage, secondPackage);
408 }
409
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100410 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100411 public void testSwitchingProviderToNonDefault() {
412 String defaultPackage = "defaultPackage";
413 String nonDefaultPackage = "nonDefaultPackage";
414 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
415 new WebViewProviderInfo(defaultPackage, "", true, false, null),
416 new WebViewProviderInfo(nonDefaultPackage, "", false, false, null)};
417 checkSwitchingProvider(packages, defaultPackage, nonDefaultPackage);
418 }
419
420 private void checkSwitchingProvider(WebViewProviderInfo[] packages, String initialPackage,
421 String finalPackage) {
Gustav Senntona9159042016-04-11 16:32:52 +0100422 checkCertainPackageUsedAfterWebViewBootPreparation(initialPackage, packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100423
424 mWebViewUpdateServiceImpl.changeProviderAndSetting(finalPackage);
Gustav Senntona9159042016-04-11 16:32:52 +0100425 checkPreparationPhasesForPackage(finalPackage, 1 /* first preparation for this package */);
Gustav Sennton53b78242016-04-07 15:56:10 +0100426
427 Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(initialPackage));
428 }
429
430 // Change provider during relro creation by using changeProviderAndSetting
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100431 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100432 public void testSwitchingProviderDuringRelroCreation() {
433 checkChangingProviderDuringRelroCreation(true);
434 }
435
436 // Change provider during relro creation by enabling a provider
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100437 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100438 public void testChangingProviderThroughEnablingDuringRelroCreation() {
439 checkChangingProviderDuringRelroCreation(false);
440 }
441
442 private void checkChangingProviderDuringRelroCreation(boolean settingsChange) {
443 String firstPackage = "first";
444 String secondPackage = "second";
445 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
446 new WebViewProviderInfo(firstPackage, "", true, false, null),
447 new WebViewProviderInfo(secondPackage, "", true, false, null)};
448 setupWithPackages(packages);
Gustav Sennton364e1602016-12-14 09:10:50 +0000449 // Have all packages be enabled, so that we can change provider however we want to
450 setEnabledAndValidPackageInfos(packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100451
452 CountDownLatch countdown = new CountDownLatch(1);
453
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100454 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100455
456 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
457 Mockito.argThat(new IsPackageInfoWithName(firstPackage)));
458
Gustav Senntonbf683e02016-09-15 14:42:50 +0100459 assertEquals(firstPackage,
460 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
Gustav Sennton53b78242016-04-07 15:56:10 +0100461
462 new Thread(new Runnable() {
463 @Override
464 public void run() {
465 WebViewProviderResponse threadResponse =
466 mWebViewUpdateServiceImpl.waitForAndGetProvider();
467 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, threadResponse.status);
468 assertEquals(secondPackage, threadResponse.packageInfo.packageName);
Gustav Sennton364e1602016-12-14 09:10:50 +0000469 // Verify that we killed the first package if we performed a settings change -
470 // otherwise we had to disable the first package, in which case its dependents
471 // should have been killed by the framework.
472 if (settingsChange) {
473 Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(firstPackage));
474 }
Gustav Sennton53b78242016-04-07 15:56:10 +0100475 countdown.countDown();
476 }
477 }).start();
478 try {
Gustav Sennton0df2c552016-06-14 15:32:19 +0100479 Thread.sleep(500); // Let the new thread run / be blocked
Gustav Sennton53b78242016-04-07 15:56:10 +0100480 } catch (InterruptedException e) {
481 }
482
483 if (settingsChange) {
484 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
485 } else {
Gustav Sennton364e1602016-12-14 09:10:50 +0000486 // Enable the second provider
Gustav Sennton53b78242016-04-07 15:56:10 +0100487 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100488 true /* valid */, true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100489 mWebViewUpdateServiceImpl.packageStateChanged(
Gustav Sennton364e1602016-12-14 09:10:50 +0000490 secondPackage, WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
491
492 // Ensure we haven't changed package yet.
493 assertEquals(firstPackage,
494 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
495
496 // Switch provider by disabling the first one
497 mTestSystemImpl.setPackageInfo(createPackageInfo(firstPackage, false /* enabled */,
498 true /* valid */, true /* installed */));
499 mWebViewUpdateServiceImpl.packageStateChanged(
500 firstPackage, WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton53b78242016-04-07 15:56:10 +0100501 }
502 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
503 // first package done, should start on second
504
505 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
506 Mockito.argThat(new IsPackageInfoWithName(secondPackage)));
507
508 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
509 // second package done, the other thread should now be unblocked
510 try {
511 countdown.await();
512 } catch (InterruptedException e) {
513 }
514 }
515
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400516 /**
517 * Scenario for testing migrating away from the fallback logic.
518 * We start with a primary package that's a disabled fallback, and an enabled secondary,
519 * so that the fallback being re-enabled will cause a provider switch, as that covers
520 * the most complex case.
521 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100522 @Test
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400523 public void testFallbackLogicMigration() {
Gustav Sennton53b78242016-04-07 15:56:10 +0100524 String primaryPackage = "primary";
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400525 String secondaryPackage = "secondary";
Gustav Sennton53b78242016-04-07 15:56:10 +0100526 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
527 new WebViewProviderInfo(
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400528 primaryPackage, "", true /* default available */, true /* fallback */, null),
Gustav Sennton53b78242016-04-07 15:56:10 +0100529 new WebViewProviderInfo(
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400530 secondaryPackage, "", true /* default available */, false /* fallback */,
531 null)};
532 setupWithPackagesAndFallbackLogic(packages);
533 mTestSystemImpl.setPackageInfo(
534 createPackageInfo(primaryPackage, false /* enabled */ , true /* valid */,
535 true /* installed */));
536 mTestSystemImpl.setPackageInfo(
537 createPackageInfo(secondaryPackage, true /* enabled */ , true /* valid */,
538 true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100539
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400540 // Check that the boot time logic re-enables and chooses the primary, and disables the
541 // fallback logic.
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100542 runWebViewBootPreparationOnMainSync();
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400543 Mockito.verify(mTestSystemImpl).enablePackageForAllUsers(
544 Matchers.anyObject(), Mockito.eq(primaryPackage), Mockito.eq(true));
545 checkPreparationPhasesForPackage(primaryPackage, 1);
546 assertFalse(mTestSystemImpl.isFallbackLogicEnabled());
Gustav Sennton53b78242016-04-07 15:56:10 +0100547
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400548 // Disable primary again
549 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, false /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100550 true /* valid */, true /* installed */));
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400551 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
552 WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
553 checkPreparationPhasesForPackage(secondaryPackage, 1);
Gustav Sennton53b78242016-04-07 15:56:10 +0100554
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400555 // Run boot logic again and check that we didn't re-enable the primary a second time.
556 runWebViewBootPreparationOnMainSync();
557 Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForAllUsers(
558 Matchers.anyObject(), Mockito.eq(primaryPackage), Mockito.eq(true));
559 checkPreparationPhasesForPackage(secondaryPackage, 2);
Gustav Sennton53b78242016-04-07 15:56:10 +0100560 }
561
562 /**
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400563 * Scenario for installing primary package when secondary in use.
564 * 1. Start with only secondary installed
565 * 2. Install primary
566 * 3. Primary should be used
Gustav Sennton53b78242016-04-07 15:56:10 +0100567 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100568 @Test
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400569 public void testInstallingPrimaryPackage() {
Gustav Sennton53b78242016-04-07 15:56:10 +0100570 String primaryPackage = "primary";
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400571 String secondaryPackage = "secondary";
Gustav Sennton53b78242016-04-07 15:56:10 +0100572 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
573 new WebViewProviderInfo(
574 primaryPackage, "", true /* default available */, false /* fallback */, null),
575 new WebViewProviderInfo(
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400576 secondaryPackage, "", true /* default available */, false /* fallback */,
577 null)};
578 setupWithPackages(packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100579 mTestSystemImpl.setPackageInfo(
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400580 createPackageInfo(secondaryPackage, true /* enabled */ , true /* valid */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100581 true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100582
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100583 runWebViewBootPreparationOnMainSync();
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400584 checkPreparationPhasesForPackage(secondaryPackage,
Gustav Senntona9159042016-04-11 16:32:52 +0100585 1 /* first preparation for this package*/);
Gustav Sennton53b78242016-04-07 15:56:10 +0100586
587 // Install primary package
588 mTestSystemImpl.setPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100589 createPackageInfo(primaryPackage, true /* enabled */ , true /* valid */,
590 true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100591 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000592 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton53b78242016-04-07 15:56:10 +0100593
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400594 // Verify primary package used as provider, and secondary package killed
Gustav Senntona9159042016-04-11 16:32:52 +0100595 checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation for this package*/);
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400596 Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(secondaryPackage));
Gustav Sennton53b78242016-04-07 15:56:10 +0100597 }
598
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100599 @Test
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400600 public void testRemovingPrimarySelectsSecondarySingleUser() {
Gustav Sennton364e1602016-12-14 09:10:50 +0000601 for (PackageRemovalType removalType : REMOVAL_TYPES) {
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400602 checkRemovingPrimarySelectsSecondary(false /* multiUser */, removalType);
Gustav Sennton364e1602016-12-14 09:10:50 +0000603 }
604 }
605
606 @Test
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400607 public void testRemovingPrimarySelectsSecondaryMultiUser() {
Gustav Sennton364e1602016-12-14 09:10:50 +0000608 for (PackageRemovalType removalType : REMOVAL_TYPES) {
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400609 checkRemovingPrimarySelectsSecondary(true /* multiUser */, removalType);
Gustav Sennton364e1602016-12-14 09:10:50 +0000610 }
611 }
612
613 /**
614 * Represents how to remove a package during a tests (disabling it / uninstalling it / hiding
615 * it).
616 */
617 private enum PackageRemovalType {
618 UNINSTALL, DISABLE, HIDE
619 }
620
621 private PackageRemovalType[] REMOVAL_TYPES = PackageRemovalType.class.getEnumConstants();
622
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400623 public void checkRemovingPrimarySelectsSecondary(boolean multiUser,
Gustav Sennton364e1602016-12-14 09:10:50 +0000624 PackageRemovalType removalType) {
Gustav Sennton53b78242016-04-07 15:56:10 +0100625 String primaryPackage = "primary";
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400626 String secondaryPackage = "secondary";
Gustav Sennton53b78242016-04-07 15:56:10 +0100627 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
628 new WebViewProviderInfo(
629 primaryPackage, "", true /* default available */, false /* fallback */, null),
630 new WebViewProviderInfo(
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400631 secondaryPackage, "", true /* default available */, false /* fallback */,
632 null)};
633 setupWithPackages(packages);
Gustav Sennton364e1602016-12-14 09:10:50 +0000634 int secondaryUserId = 10;
635 int userIdToChangePackageFor = multiUser ? secondaryUserId : TestSystemImpl.PRIMARY_USER_ID;
636 if (multiUser) {
637 mTestSystemImpl.addUser(secondaryUserId);
638 setEnabledAndValidPackageInfosForUser(secondaryUserId, packages);
639 }
640 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100641
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100642 runWebViewBootPreparationOnMainSync();
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100643 checkPreparationPhasesForPackage(primaryPackage, 1);
644
Gustav Sennton364e1602016-12-14 09:10:50 +0000645 boolean enabled = !(removalType == PackageRemovalType.DISABLE);
646 boolean installed = !(removalType == PackageRemovalType.UNINSTALL);
647 boolean hidden = (removalType == PackageRemovalType.HIDE);
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400648 // Disable primary package and ensure secondary becomes used
Gustav Sennton364e1602016-12-14 09:10:50 +0000649 mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
650 createPackageInfo(primaryPackage, enabled /* enabled */, true /* valid */,
651 installed /* installed */, null /* signature */, 0 /* updateTime */,
652 hidden /* hidden */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100653 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000654 removalType == PackageRemovalType.DISABLE
655 ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_REMOVED,
656 userIdToChangePackageFor); // USER ID
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400657 checkPreparationPhasesForPackage(secondaryPackage, 1);
Gustav Sennton53b78242016-04-07 15:56:10 +0100658
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400659 // Again enable primary package and verify primary is used
Gustav Sennton364e1602016-12-14 09:10:50 +0000660 mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100661 createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
662 true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100663 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000664 removalType == PackageRemovalType.DISABLE
665 ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_ADDED,
666 userIdToChangePackageFor);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100667 checkPreparationPhasesForPackage(primaryPackage, 2);
Gustav Sennton53b78242016-04-07 15:56:10 +0100668 }
669
Gustav Sennton53b78242016-04-07 15:56:10 +0100670 /**
Gustav Sennton364e1602016-12-14 09:10:50 +0000671 * Ensures that adding a new user for which the current WebView package is uninstalled causes a
672 * change of WebView provider.
673 */
674 @Test
675 public void testAddingNewUserWithUninstalledPackage() {
676 String primaryPackage = "primary";
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400677 String secondaryPackage = "secondary";
Gustav Sennton364e1602016-12-14 09:10:50 +0000678 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
679 new WebViewProviderInfo(
680 primaryPackage, "", true /* default available */, false /* fallback */, null),
681 new WebViewProviderInfo(
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400682 secondaryPackage, "", true /* default available */, false /* fallback */,
683 null)};
684 setupWithPackages(packages);
Gustav Sennton364e1602016-12-14 09:10:50 +0000685 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
686 int newUser = 100;
687 mTestSystemImpl.addUser(newUser);
688 // Let the primary package be uninstalled for the new user
689 mTestSystemImpl.setPackageInfoForUser(newUser,
690 createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
691 false /* installed */));
692 mTestSystemImpl.setPackageInfoForUser(newUser,
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400693 createPackageInfo(secondaryPackage, true /* enabled */, true /* valid */,
Gustav Sennton364e1602016-12-14 09:10:50 +0000694 true /* installed */));
695 mWebViewUpdateServiceImpl.handleNewUser(newUser);
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400696 checkPreparationPhasesForPackage(secondaryPackage, 1 /* numRelros */);
Gustav Sennton364e1602016-12-14 09:10:50 +0000697 }
698
699 /**
Gustav Sennton53b78242016-04-07 15:56:10 +0100700 * Timing dependent test where we verify that the list of valid webview packages becoming empty
701 * at a certain point doesn't crash us or break our state.
702 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100703 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100704 public void testNotifyRelroDoesntCrashIfNoPackages() {
705 String firstPackage = "first";
706 String secondPackage = "second";
707 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
708 new WebViewProviderInfo(firstPackage, "", true /* default available */,
709 false /* fallback */, null),
710 new WebViewProviderInfo(secondPackage, "", true /* default available */,
711 false /* fallback */, null)};
712 setupWithPackages(packages);
713 // Add (enabled and valid) package infos for each provider
714 setEnabledAndValidPackageInfos(packages);
715
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100716 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100717
718 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
719 Mockito.argThat(new IsPackageInfoWithName(firstPackage)));
720
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100721 // Change provider during relro creation to enter a state where we are
722 // waiting for relro creation to complete just to re-run relro creation.
723 // (so that in next notifyRelroCreationCompleted() call we have to list webview packages)
Gustav Sennton53b78242016-04-07 15:56:10 +0100724 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
725
726 // Make packages invalid to cause exception to be thrown
727 mTestSystemImpl.setPackageInfo(createPackageInfo(firstPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100728 false /* valid */, true /* installed */, null /* signatures */,
729 0 /* updateTime */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100730 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100731 false /* valid */, true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100732
733 // This shouldn't throw an exception!
734 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
735
736 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
737 assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
738
739 // Now make a package valid again and verify that we can switch back to that
740 mTestSystemImpl.setPackageInfo(createPackageInfo(firstPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100741 true /* valid */, true /* installed */, null /* signatures */,
742 1 /* updateTime */ ));
Gustav Sennton53b78242016-04-07 15:56:10 +0100743
744 mWebViewUpdateServiceImpl.packageStateChanged(firstPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000745 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton53b78242016-04-07 15:56:10 +0100746
Gustav Senntona9159042016-04-11 16:32:52 +0100747 // Ensure we use firstPackage
748 checkPreparationPhasesForPackage(firstPackage, 2 /* second preparation for this package */);
749 }
Gustav Sennton53b78242016-04-07 15:56:10 +0100750
Gustav Senntona9159042016-04-11 16:32:52 +0100751 /**
752 * Verify that even if a user-chosen package is removed temporarily we start using it again when
753 * it is added back.
754 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100755 @Test
Gustav Senntona9159042016-04-11 16:32:52 +0100756 public void testTempRemovePackageDoesntSwitchProviderPermanently() {
757 String firstPackage = "first";
758 String secondPackage = "second";
759 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
760 new WebViewProviderInfo(firstPackage, "", true /* default available */,
761 false /* fallback */, null),
762 new WebViewProviderInfo(secondPackage, "", true /* default available */,
763 false /* fallback */, null)};
764 checkCertainPackageUsedAfterWebViewBootPreparation(firstPackage, packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100765
Gustav Senntona9159042016-04-11 16:32:52 +0100766 // Explicitly use the second package
767 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
768 checkPreparationPhasesForPackage(secondPackage, 1 /* first time for this package */);
769
770 // Remove second package (invalidate it) and verify that first package is used
771 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100772 false /* valid */, true /* installed */));
Gustav Senntona9159042016-04-11 16:32:52 +0100773 mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000774 WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Senntona9159042016-04-11 16:32:52 +0100775 checkPreparationPhasesForPackage(firstPackage, 2 /* second time for this package */);
776
777 // Now make the second package valid again and verify that it is used again
778 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100779 true /* valid */, true /* installed */));
Gustav Senntona9159042016-04-11 16:32:52 +0100780 mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000781 WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Senntona9159042016-04-11 16:32:52 +0100782 checkPreparationPhasesForPackage(secondPackage, 2 /* second time for this package */);
783 }
784
785 /**
786 * Ensure that we update the user-chosen setting across boots if the chosen package is no
787 * longer installed and valid.
788 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100789 @Test
Gustav Senntona9159042016-04-11 16:32:52 +0100790 public void testProviderSettingChangedDuringBootIfProviderNotAvailable() {
791 String chosenPackage = "chosenPackage";
792 String nonChosenPackage = "non-chosenPackage";
793 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
794 new WebViewProviderInfo(chosenPackage, "", true /* default available */,
795 false /* fallback */, null),
796 new WebViewProviderInfo(nonChosenPackage, "", true /* default available */,
797 false /* fallback */, null)};
798
799 setupWithPackages(packages);
800 // Only 'install' nonChosenPackage
801 mTestSystemImpl.setPackageInfo(
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400802 createPackageInfo(nonChosenPackage, true /* enabled */, true /* valid */,
803 true /* installed */));
Gustav Senntona9159042016-04-11 16:32:52 +0100804
805 // Set user-chosen package
806 mTestSystemImpl.updateUserSetting(null, chosenPackage);
807
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100808 runWebViewBootPreparationOnMainSync();
Gustav Senntona9159042016-04-11 16:32:52 +0100809
810 // Verify that we switch the setting to point to the current package
811 Mockito.verify(mTestSystemImpl).updateUserSetting(
812 Mockito.anyObject(), Mockito.eq(nonChosenPackage));
813 assertEquals(nonChosenPackage, mTestSystemImpl.getUserChosenWebViewProvider(null));
814
815 checkPreparationPhasesForPackage(nonChosenPackage, 1);
Gustav Sennton53b78242016-04-07 15:56:10 +0100816 }
817
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100818 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100819 public void testRecoverFailedListingWebViewPackagesSettingsChange() {
820 checkRecoverAfterFailListingWebviewPackages(true);
821 }
822
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100823 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100824 public void testRecoverFailedListingWebViewPackagesAddedPackage() {
825 checkRecoverAfterFailListingWebviewPackages(false);
826 }
827
828 /**
829 * Test that we can recover correctly from failing to list WebView packages.
830 * settingsChange: whether to fail during changeProviderAndSetting or packageStateChanged
831 */
832 public void checkRecoverAfterFailListingWebviewPackages(boolean settingsChange) {
833 String firstPackage = "first";
834 String secondPackage = "second";
835 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
836 new WebViewProviderInfo(firstPackage, "", true /* default available */,
837 false /* fallback */, null),
838 new WebViewProviderInfo(secondPackage, "", true /* default available */,
839 false /* fallback */, null)};
840 checkCertainPackageUsedAfterWebViewBootPreparation(firstPackage, packages);
841
842 // Make both packages invalid so that we fail listing WebView packages
843 mTestSystemImpl.setPackageInfo(createPackageInfo(firstPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100844 false /* valid */, true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100845 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100846 false /* valid */, true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100847
848 // Change package to hit the webview packages listing problem.
849 if (settingsChange) {
850 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
851 } else {
852 mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000853 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100854 }
855
856 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
857 assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
858
859 // Make second package valid and verify that we can load it again
860 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100861 true /* valid */, true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100862
863 mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000864 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100865
866
867 checkPreparationPhasesForPackage(secondPackage, 1);
868 }
869
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100870 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100871 public void testDontKillIfPackageReplaced() {
872 checkDontKillIfPackageRemoved(true);
873 }
874
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100875 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100876 public void testDontKillIfPackageRemoved() {
877 checkDontKillIfPackageRemoved(false);
878 }
879
880 public void checkDontKillIfPackageRemoved(boolean replaced) {
881 String firstPackage = "first";
882 String secondPackage = "second";
883 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
884 new WebViewProviderInfo(firstPackage, "", true /* default available */,
885 false /* fallback */, null),
886 new WebViewProviderInfo(secondPackage, "", true /* default available */,
887 false /* fallback */, null)};
888 checkCertainPackageUsedAfterWebViewBootPreparation(firstPackage, packages);
889
890 // Replace or remove the current webview package
891 if (replaced) {
892 mTestSystemImpl.setPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100893 createPackageInfo(firstPackage, true /* enabled */, false /* valid */,
894 true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100895 mWebViewUpdateServiceImpl.packageStateChanged(firstPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000896 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100897 } else {
898 mTestSystemImpl.removePackageInfo(firstPackage);
899 mWebViewUpdateServiceImpl.packageStateChanged(firstPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000900 WebViewUpdateService.PACKAGE_REMOVED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100901 }
902
903 checkPreparationPhasesForPackage(secondPackage, 1);
904
905 Mockito.verify(mTestSystemImpl, Mockito.never()).killPackageDependents(
906 Mockito.anyObject());
907 }
908
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100909 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100910 public void testKillIfSettingChanged() {
911 String firstPackage = "first";
912 String secondPackage = "second";
913 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
914 new WebViewProviderInfo(firstPackage, "", true /* default available */,
915 false /* fallback */, null),
916 new WebViewProviderInfo(secondPackage, "", true /* default available */,
917 false /* fallback */, null)};
918 checkCertainPackageUsedAfterWebViewBootPreparation(firstPackage, packages);
919
920 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
921
922 checkPreparationPhasesForPackage(secondPackage, 1);
923
924 Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(firstPackage));
925 }
926
927 /**
928 * Test that we kill apps using an old provider when we change the provider setting, even if the
929 * new provider is not the one we intended to change to.
930 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100931 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100932 public void testKillIfChangeProviderIncorrectly() {
933 String firstPackage = "first";
934 String secondPackage = "second";
935 String thirdPackage = "third";
936 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
937 new WebViewProviderInfo(firstPackage, "", true /* default available */,
938 false /* fallback */, null),
939 new WebViewProviderInfo(secondPackage, "", true /* default available */,
940 false /* fallback */, null),
941 new WebViewProviderInfo(thirdPackage, "", true /* default available */,
942 false /* fallback */, null)};
943 setupWithPackages(packages);
944 setEnabledAndValidPackageInfos(packages);
945
946 // Start with the setting pointing to the third package
947 mTestSystemImpl.updateUserSetting(null, thirdPackage);
948
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100949 runWebViewBootPreparationOnMainSync();
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100950 checkPreparationPhasesForPackage(thirdPackage, 1);
951
952 mTestSystemImpl.setPackageInfo(
Torne (Richard Coles)ef478902019-03-28 15:03:21 -0400953 createPackageInfo(secondPackage, true /* enabled */, false /* valid */,
954 true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100955
956 // Try to switch to the invalid second package, this should result in switching to the first
957 // package, since that is more preferred than the third one.
958 assertEquals(firstPackage,
959 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage));
960
961 checkPreparationPhasesForPackage(firstPackage, 1);
962
963 Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(thirdPackage));
964 }
Gustav Sennton18c9e152016-04-15 15:24:53 +0100965
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +0000966 @Test
Gustav Sennton18c9e152016-04-15 15:24:53 +0100967 public void testLowerPackageVersionNotValid() {
Hui Shu826a24b2016-04-26 14:53:40 -0700968 checkPackageVersions(new int[]{200000} /* system version */, 100000/* candidate version */,
969 false /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +0100970 }
971
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +0000972 @Test
Gustav Sennton18c9e152016-04-15 15:24:53 +0100973 public void testEqualPackageVersionValid() {
Hui Shu826a24b2016-04-26 14:53:40 -0700974 checkPackageVersions(new int[]{100000} /* system version */, 100000 /* candidate version */,
975 true /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +0100976 }
977
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +0000978 @Test
Gustav Sennton18c9e152016-04-15 15:24:53 +0100979 public void testGreaterPackageVersionValid() {
Hui Shu826a24b2016-04-26 14:53:40 -0700980 checkPackageVersions(new int[]{100000} /* system versions */, 200000 /* candidate version */,
981 true /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +0100982 }
983
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +0000984 @Test
Hui Shu826a24b2016-04-26 14:53:40 -0700985 public void testLastFiveDigitsIgnored() {
986 checkPackageVersions(new int[]{654321} /* system version */, 612345 /* candidate version */,
987 true /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +0100988 }
989
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +0000990 @Test
Hui Shu826a24b2016-04-26 14:53:40 -0700991 public void testMinimumSystemVersionUsedTwoDefaultsCandidateValid() {
992 checkPackageVersions(new int[]{300000, 100000} /* system versions */,
993 200000 /* candidate version */, true /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +0100994 }
995
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +0000996 @Test
Hui Shu826a24b2016-04-26 14:53:40 -0700997 public void testMinimumSystemVersionUsedTwoDefaultsCandidateInvalid() {
998 checkPackageVersions(new int[]{300000, 200000} /* system versions */,
999 100000 /* candidate version */, false /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001000 }
1001
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001002 @Test
Hui Shu826a24b2016-04-26 14:53:40 -07001003 public void testMinimumSystemVersionUsedSeveralDefaultsCandidateValid() {
1004 checkPackageVersions(new int[]{100000, 200000, 300000, 400000, 500000} /* system versions */,
1005 100000 /* candidate version */, true /* expected validity */);
1006 }
1007
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001008 @Test
Hui Shu826a24b2016-04-26 14:53:40 -07001009 public void testMinimumSystemVersionUsedSeveralDefaultsCandidateInvalid() {
1010 checkPackageVersions(new int[]{200000, 300000, 400000, 500000, 600000} /* system versions */,
1011 100000 /* candidate version */, false /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001012 }
1013
Gustav Sennton18c9e152016-04-15 15:24:53 +01001014 /**
1015 * Utility method for checking that package version restriction works as it should.
1016 * I.e. that a package with lower version than the system-default is not valid and that a
1017 * package with greater than or equal version code is considered valid.
1018 */
Hui Shu826a24b2016-04-26 14:53:40 -07001019 private void checkPackageVersions(int[] systemVersions, int candidateVersion,
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001020 boolean candidateShouldBeValid) {
Gustav Sennton18c9e152016-04-15 15:24:53 +01001021 int numSystemPackages = systemVersions.length;
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001022 int numPackages = systemVersions.length + 1;
Hui Shu826a24b2016-04-26 14:53:40 -07001023 String candidatePackage = "candidatePackage";
Gustav Sennton18c9e152016-04-15 15:24:53 +01001024 String systemPackage = "systemPackage";
Gustav Sennton18c9e152016-04-15 15:24:53 +01001025
1026 // Each package needs a valid signature since we set isDebuggable to false
1027 Signature signature = new Signature("11");
1028 String encodedSignatureString =
1029 Base64.encodeToString(signature.toByteArray(), Base64.DEFAULT);
1030
1031 // Set up config
Hui Shu826a24b2016-04-26 14:53:40 -07001032 // 1. candidatePackage
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001033 // 2-N. default available packages
Gustav Sennton18c9e152016-04-15 15:24:53 +01001034 WebViewProviderInfo[] packages = new WebViewProviderInfo[numPackages];
Hui Shu826a24b2016-04-26 14:53:40 -07001035 packages[0] = new WebViewProviderInfo(candidatePackage, "",
Gustav Sennton18c9e152016-04-15 15:24:53 +01001036 false /* available by default */, false /* fallback */,
1037 new String[]{encodedSignatureString});
1038 for(int n = 1; n < numSystemPackages + 1; n++) {
1039 packages[n] = new WebViewProviderInfo(systemPackage + n, "",
1040 true /* available by default */, false /* fallback */,
1041 new String[]{encodedSignatureString});
1042 }
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001043 setupWithPackagesNonDebuggable(packages);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001044
1045 // Set package infos
1046 mTestSystemImpl.setPackageInfo(
Hui Shu826a24b2016-04-26 14:53:40 -07001047 createPackageInfo(candidatePackage, true /* enabled */, true /* valid */,
Gustav Senntonfd222fc22016-06-16 20:24:23 +01001048 true /* installed */, new Signature[]{signature}, 0 /* updateTime */,
1049 false /* hidden */, candidateVersion, false /* isSystemApp */));
Gustav Sennton18c9e152016-04-15 15:24:53 +01001050 for(int n = 1; n < numSystemPackages + 1; n++) {
1051 mTestSystemImpl.setPackageInfo(
1052 createPackageInfo(systemPackage + n, true /* enabled */, true /* valid */,
Gustav Senntonfd222fc22016-06-16 20:24:23 +01001053 true /* installed */, new Signature[]{signature}, 0 /* updateTime */,
1054 false /* hidden */, systemVersions[n-1], true /* isSystemApp */));
Gustav Sennton18c9e152016-04-15 15:24:53 +01001055 }
Gustav Sennton18c9e152016-04-15 15:24:53 +01001056
1057 WebViewProviderInfo[] validPackages = mWebViewUpdateServiceImpl.getValidWebViewPackages();
Hui Shu826a24b2016-04-26 14:53:40 -07001058 int expectedNumValidPackages = numSystemPackages;
1059 if (candidateShouldBeValid) {
1060 expectedNumValidPackages++;
Gustav Sennton18c9e152016-04-15 15:24:53 +01001061 } else {
Hui Shu826a24b2016-04-26 14:53:40 -07001062 // Ensure the candidate package is not one of the valid packages
Gustav Sennton18c9e152016-04-15 15:24:53 +01001063 for(int n = 0; n < validPackages.length; n++) {
Hui Shu826a24b2016-04-26 14:53:40 -07001064 assertFalse(candidatePackage.equals(validPackages[n].packageName));
Gustav Sennton18c9e152016-04-15 15:24:53 +01001065 }
1066 }
1067
Hui Shu826a24b2016-04-26 14:53:40 -07001068 assertEquals(expectedNumValidPackages, validPackages.length);
1069
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001070 runWebViewBootPreparationOnMainSync();
Gustav Sennton18c9e152016-04-15 15:24:53 +01001071
1072 // The non-system package is not available by default so it shouldn't be used here
1073 checkPreparationPhasesForPackage(systemPackage + "1", 1);
1074
Hui Shu826a24b2016-04-26 14:53:40 -07001075 // Try explicitly switching to the candidate package
1076 String packageChange = mWebViewUpdateServiceImpl.changeProviderAndSetting(candidatePackage);
1077 if (candidateShouldBeValid) {
1078 assertEquals(candidatePackage, packageChange);
1079 checkPreparationPhasesForPackage(candidatePackage, 1);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001080 } else {
1081 assertEquals(systemPackage + "1", packageChange);
1082 // We didn't change package so the webview preparation won't run here
1083 }
1084 }
Gustav Senntonfd222fc22016-06-16 20:24:23 +01001085
Gustav Sennton364e1602016-12-14 09:10:50 +00001086 /**
1087 * Ensure that the update service does use an uninstalled package when that is the only
1088 * package available.
1089 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001090 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001091 public void testWithSingleUninstalledPackage() {
1092 String testPackageName = "test.package.name";
1093 WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
1094 new WebViewProviderInfo(testPackageName, "",
1095 true /*default available*/, false /* fallback */, null)};
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001096 setupWithPackages(webviewPackages);
Gustav Sennton0df2c552016-06-14 15:32:19 +01001097 mTestSystemImpl.setPackageInfo(createPackageInfo(testPackageName, true /* enabled */,
1098 true /* valid */, false /* installed */));
1099
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001100 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001101
Gustav Sennton963dbbb2017-04-06 16:18:02 +01001102 Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
1103 Matchers.anyObject());
1104 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
1105 assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
1106 assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage());
Gustav Sennton0df2c552016-06-14 15:32:19 +01001107 }
1108
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001109 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001110 public void testNonhiddenPackageUserOverHidden() {
Gustav Sennton364e1602016-12-14 09:10:50 +00001111 checkVisiblePackageUserOverNonVisible(false /* multiUser*/, PackageRemovalType.HIDE);
1112 checkVisiblePackageUserOverNonVisible(true /* multiUser*/, PackageRemovalType.HIDE);
Gustav Sennton0df2c552016-06-14 15:32:19 +01001113 }
1114
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001115 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001116 public void testInstalledPackageUsedOverUninstalled() {
Gustav Sennton364e1602016-12-14 09:10:50 +00001117 checkVisiblePackageUserOverNonVisible(false /* multiUser*/, PackageRemovalType.UNINSTALL);
1118 checkVisiblePackageUserOverNonVisible(true /* multiUser*/, PackageRemovalType.UNINSTALL);
Gustav Sennton0df2c552016-06-14 15:32:19 +01001119 }
1120
Gustav Sennton364e1602016-12-14 09:10:50 +00001121 private void checkVisiblePackageUserOverNonVisible(boolean multiUser,
1122 PackageRemovalType removalType) {
1123 assert removalType != PackageRemovalType.DISABLE;
1124 boolean testUninstalled = removalType == PackageRemovalType.UNINSTALL;
1125 boolean testHidden = removalType == PackageRemovalType.HIDE;
Gustav Sennton0df2c552016-06-14 15:32:19 +01001126 String installedPackage = "installedPackage";
1127 String uninstalledPackage = "uninstalledPackage";
1128 WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
1129 new WebViewProviderInfo(uninstalledPackage, "", true /* available by default */,
1130 false /* fallback */, null),
1131 new WebViewProviderInfo(installedPackage, "", true /* available by default */,
1132 false /* fallback */, null)};
1133
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001134 setupWithPackages(webviewPackages);
Gustav Sennton364e1602016-12-14 09:10:50 +00001135 int secondaryUserId = 5;
1136 if (multiUser) {
1137 mTestSystemImpl.addUser(secondaryUserId);
1138 // Install all packages for the primary user.
1139 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, webviewPackages);
1140 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(
1141 installedPackage, true /* enabled */, true /* valid */, true /* installed */));
1142 // Hide or uninstall the primary package for the second user
1143 mTestSystemImpl.setPackageInfo(createPackageInfo(uninstalledPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +01001144 true /* valid */, (testUninstalled ? false : true) /* installed */,
1145 null /* signatures */, 0 /* updateTime */, (testHidden ? true : false)));
Gustav Sennton364e1602016-12-14 09:10:50 +00001146 } else {
1147 mTestSystemImpl.setPackageInfo(createPackageInfo(installedPackage, true /* enabled */,
1148 true /* valid */, true /* installed */));
1149 // Hide or uninstall the primary package
1150 mTestSystemImpl.setPackageInfo(createPackageInfo(uninstalledPackage, true /* enabled */,
1151 true /* valid */, (testUninstalled ? false : true) /* installed */,
1152 null /* signatures */, 0 /* updateTime */, (testHidden ? true : false)));
1153 }
Gustav Sennton0df2c552016-06-14 15:32:19 +01001154
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001155 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001156
1157 checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
1158 }
1159
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001160 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001161 public void testCantSwitchToHiddenPackage () {
1162 checkCantSwitchToNonVisiblePackage(false /* true == uninstalled, false == hidden */);
1163 }
1164
1165
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001166 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001167 public void testCantSwitchToUninstalledPackage () {
1168 checkCantSwitchToNonVisiblePackage(true /* true == uninstalled, false == hidden */);
1169 }
1170
1171 /**
Gustav Sennton364e1602016-12-14 09:10:50 +00001172 * Ensure that we won't prioritize an uninstalled (or hidden) package even if it is user-chosen.
Gustav Sennton0df2c552016-06-14 15:32:19 +01001173 */
1174 private void checkCantSwitchToNonVisiblePackage(boolean uninstalledNotHidden) {
1175 boolean testUninstalled = uninstalledNotHidden;
1176 boolean testHidden = !uninstalledNotHidden;
1177 String installedPackage = "installedPackage";
1178 String uninstalledPackage = "uninstalledPackage";
1179 WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
1180 new WebViewProviderInfo(uninstalledPackage, "", true /* available by default */,
1181 false /* fallback */, null),
1182 new WebViewProviderInfo(installedPackage, "", true /* available by default */,
1183 false /* fallback */, null)};
1184
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001185 setupWithPackages(webviewPackages);
Gustav Sennton364e1602016-12-14 09:10:50 +00001186 int secondaryUserId = 412;
1187 mTestSystemImpl.addUser(secondaryUserId);
1188
1189 // Let all packages be installed and enabled for the primary user.
1190 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, webviewPackages);
1191 // Only uninstall the 'uninstalled package' for the secondary user.
1192 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(installedPackage,
1193 true /* enabled */, true /* valid */, true /* installed */));
1194 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(uninstalledPackage,
1195 true /* enabled */, true /* valid */, !testUninstalled /* installed */,
1196 null /* signatures */, 0 /* updateTime */, testHidden /* hidden */));
Gustav Sennton0df2c552016-06-14 15:32:19 +01001197
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001198 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001199
1200 checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
1201
Gustav Sennton0df2c552016-06-14 15:32:19 +01001202 // ensure that we don't switch to the uninstalled package (it will be used if it becomes
1203 // installed later)
1204 assertEquals(installedPackage,
1205 mWebViewUpdateServiceImpl.changeProviderAndSetting(uninstalledPackage));
1206
Gustav Sennton364e1602016-12-14 09:10:50 +00001207 // Ensure both packages are considered valid.
1208 assertEquals(2, mWebViewUpdateServiceImpl.getValidWebViewPackages().length);
1209
1210
Gustav Sennton0df2c552016-06-14 15:32:19 +01001211 // We should only have called onWebViewProviderChanged once (before calling
1212 // changeProviderAndSetting
1213 Mockito.verify(mTestSystemImpl, Mockito.times(1)).onWebViewProviderChanged(
1214 Mockito.argThat(new IsPackageInfoWithName(installedPackage)));
1215 }
1216
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001217 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001218 public void testHiddenPackageNotPrioritizedEvenIfChosen() {
1219 checkNonvisiblePackageNotPrioritizedEvenIfChosen(
1220 false /* true == uninstalled, false == hidden */);
1221 }
1222
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001223 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001224 public void testUninstalledPackageNotPrioritizedEvenIfChosen() {
1225 checkNonvisiblePackageNotPrioritizedEvenIfChosen(
1226 true /* true == uninstalled, false == hidden */);
1227 }
1228
1229 public void checkNonvisiblePackageNotPrioritizedEvenIfChosen(boolean uninstalledNotHidden) {
1230 boolean testUninstalled = uninstalledNotHidden;
1231 boolean testHidden = !uninstalledNotHidden;
1232 String installedPackage = "installedPackage";
1233 String uninstalledPackage = "uninstalledPackage";
1234 WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
1235 new WebViewProviderInfo(uninstalledPackage, "", true /* available by default */,
1236 false /* fallback */, null),
1237 new WebViewProviderInfo(installedPackage, "", true /* available by default */,
1238 false /* fallback */, null)};
1239
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001240 setupWithPackages(webviewPackages);
Gustav Sennton364e1602016-12-14 09:10:50 +00001241 int secondaryUserId = 4;
1242 mTestSystemImpl.addUser(secondaryUserId);
1243
1244 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, webviewPackages);
1245 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(installedPackage,
1246 true /* enabled */, true /* valid */, true /* installed */));
1247 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(uninstalledPackage,
1248 true /* enabled */, true /* valid */,
1249 (testUninstalled ? false : true) /* installed */, null /* signatures */,
1250 0 /* updateTime */, (testHidden ? true : false) /* hidden */));
Gustav Sennton0df2c552016-06-14 15:32:19 +01001251
1252 // Start with the setting pointing to the uninstalled package
1253 mTestSystemImpl.updateUserSetting(null, uninstalledPackage);
1254
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001255 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001256
1257 checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
1258 }
1259
Gustav Sennton364e1602016-12-14 09:10:50 +00001260 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001261 public void testPreparationRunsIffNewPackage() {
1262 String primaryPackage = "primary";
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001263 String secondaryPackage = "secondary";
Gustav Sennton0df2c552016-06-14 15:32:19 +01001264 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1265 new WebViewProviderInfo(
1266 primaryPackage, "", true /* default available */, false /* fallback */, null),
1267 new WebViewProviderInfo(
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001268 secondaryPackage, "", true /* default available */, false /* fallback */,
1269 null)};
1270 setupWithPackages(packages);
Gustav Sennton0df2c552016-06-14 15:32:19 +01001271 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1272 true /* valid */, true /* installed */, null /* signatures */,
1273 10 /* lastUpdateTime*/ ));
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001274 mTestSystemImpl.setPackageInfo(createPackageInfo(secondaryPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +01001275 true /* valid */, true /* installed */));
1276
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001277 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001278
1279 checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
Gustav Sennton0df2c552016-06-14 15:32:19 +01001280
1281 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1282 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0 /* userId */);
1283 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1284 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 1 /* userId */);
1285 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1286 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 2 /* userId */);
1287 // package still has the same update-time so we shouldn't run preparation here
1288 Mockito.verify(mTestSystemImpl, Mockito.times(1)).onWebViewProviderChanged(
1289 Mockito.argThat(new IsPackageInfoWithName(primaryPackage)));
Gustav Sennton0df2c552016-06-14 15:32:19 +01001290
1291 // Ensure we can still load the package
1292 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
1293 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, response.status);
1294 assertEquals(primaryPackage, response.packageInfo.packageName);
1295
1296
1297 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1298 true /* valid */, true /* installed */, null /* signatures */,
1299 20 /* lastUpdateTime*/ ));
1300 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1301 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
1302 // The package has now changed - ensure that we have run the preparation phase a second time
1303 checkPreparationPhasesForPackage(primaryPackage, 2 /* second preparation phase */);
1304
1305
1306 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1307 true /* valid */, true /* installed */, null /* signatures */,
1308 50 /* lastUpdateTime*/ ));
1309 // Receive intent for different user
1310 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1311 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 2);
1312
1313 checkPreparationPhasesForPackage(primaryPackage, 3 /* third preparation phase */);
1314 }
Gustav Senntonbf683e02016-09-15 14:42:50 +01001315
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001316 @Test
Gustav Senntonbf683e02016-09-15 14:42:50 +01001317 public void testGetCurrentWebViewPackage() {
1318 PackageInfo firstPackage = createPackageInfo("first", true /* enabled */,
1319 true /* valid */, true /* installed */);
Dianne Hackborn891b74c2017-12-11 16:54:27 -08001320 firstPackage.setLongVersionCode(100);
Gustav Senntonbf683e02016-09-15 14:42:50 +01001321 firstPackage.versionName = "first package version";
1322 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1323 new WebViewProviderInfo(firstPackage.packageName, "", true, false, null)};
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001324 setupWithPackages(packages);
Gustav Senntonbf683e02016-09-15 14:42:50 +01001325 mTestSystemImpl.setPackageInfo(firstPackage);
1326
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001327 runWebViewBootPreparationOnMainSync();
Gustav Senntonbf683e02016-09-15 14:42:50 +01001328
1329 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
1330 Mockito.argThat(new IsPackageInfoWithName(firstPackage.packageName)));
1331
1332 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
1333
1334 // Ensure the API is correct before running waitForAndGetProvider
1335 assertEquals(firstPackage.packageName,
1336 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
Dianne Hackborn3accca02013-09-20 09:32:11 -07001337 assertEquals(firstPackage.getLongVersionCode(),
1338 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().getLongVersionCode());
Gustav Senntonbf683e02016-09-15 14:42:50 +01001339 assertEquals(firstPackage.versionName,
1340 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionName);
1341
1342 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
1343 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, response.status);
1344 assertEquals(firstPackage.packageName, response.packageInfo.packageName);
1345
1346 // Ensure the API is still correct after running waitForAndGetProvider
1347 assertEquals(firstPackage.packageName,
1348 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
Dianne Hackborn3accca02013-09-20 09:32:11 -07001349 assertEquals(firstPackage.getLongVersionCode(),
1350 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().getLongVersionCode());
Gustav Senntonbf683e02016-09-15 14:42:50 +01001351 assertEquals(firstPackage.versionName,
1352 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionName);
1353 }
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001354
1355 @Test
1356 public void testMultiProcessEnabledByDefault() {
Gustav Senntonb2650162017-04-07 14:41:38 +01001357 testMultiProcessByDefault(true /* enabledByDefault */);
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001358 }
1359
1360 @Test
1361 public void testMultiProcessDisabledByDefault() {
Gustav Senntonb2650162017-04-07 14:41:38 +01001362 testMultiProcessByDefault(false /* enabledByDefault */);
1363 }
1364
1365 private void testMultiProcessByDefault(boolean enabledByDefault) {
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001366 String primaryPackage = "primary";
1367 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1368 new WebViewProviderInfo(
1369 primaryPackage, "", true /* default available */, false /* fallback */, null)};
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001370 setupWithPackagesAndMultiProcess(packages, enabledByDefault);
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001371 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1372 true /* valid */, true /* installed */, null /* signatures */,
1373 10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
1374 false /* isSystemApp */));
1375
1376 runWebViewBootPreparationOnMainSync();
1377 checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
1378
1379 // Check it's off by default
Gustav Senntonb2650162017-04-07 14:41:38 +01001380 assertEquals(enabledByDefault, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001381
1382 // Test toggling it
Gustav Senntonb2650162017-04-07 14:41:38 +01001383 mWebViewUpdateServiceImpl.enableMultiProcess(!enabledByDefault);
1384 assertEquals(!enabledByDefault, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
1385 mWebViewUpdateServiceImpl.enableMultiProcess(enabledByDefault);
1386 assertEquals(enabledByDefault, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001387 }
Gustav Sennton564c2fd2017-01-30 18:08:01 +00001388
Gustav Senntonb2650162017-04-07 14:41:38 +01001389 @Test
1390 public void testMultiProcessEnabledByDefaultWithSettingsValue() {
1391 testMultiProcessByDefaultWithSettingsValue(
1392 true /* enabledByDefault */, Integer.MIN_VALUE, false /* expectEnabled */);
1393 testMultiProcessByDefaultWithSettingsValue(
1394 true /* enabledByDefault */, -999999, true /* expectEnabled */);
1395 testMultiProcessByDefaultWithSettingsValue(
1396 true /* enabledByDefault */, 0, true /* expectEnabled */);
1397 testMultiProcessByDefaultWithSettingsValue(
1398 true /* enabledByDefault */, 999999, true /* expectEnabled */);
1399 }
1400
1401 @Test
1402 public void testMultiProcessDisabledByDefaultWithSettingsValue() {
1403 testMultiProcessByDefaultWithSettingsValue(
1404 false /* enabledByDefault */, Integer.MIN_VALUE, false /* expectEnabled */);
1405 testMultiProcessByDefaultWithSettingsValue(
1406 false /* enabledByDefault */, 0, false /* expectEnabled */);
1407 testMultiProcessByDefaultWithSettingsValue(
1408 false /* enabledByDefault */, 999999, false /* expectEnabled */);
1409 testMultiProcessByDefaultWithSettingsValue(
1410 false /* enabledByDefault */, Integer.MAX_VALUE, true /* expectEnabled */);
1411 }
1412
1413 /**
1414 * Test the logic of the multiprocess setting depending on whether multiprocess is enabled by
1415 * default, and what the setting is set to.
1416 * @param enabledByDefault whether multiprocess is enabled by default.
1417 * @param settingValue value of the multiprocess setting.
1418 */
1419 private void testMultiProcessByDefaultWithSettingsValue(
1420 boolean enabledByDefault, int settingValue, boolean expectEnabled) {
1421 String primaryPackage = "primary";
1422 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1423 new WebViewProviderInfo(
1424 primaryPackage, "", true /* default available */, false /* fallback */, null)};
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001425 setupWithPackagesAndMultiProcess(packages, enabledByDefault);
Gustav Senntonb2650162017-04-07 14:41:38 +01001426 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1427 true /* valid */, true /* installed */, null /* signatures */,
1428 10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
1429 false /* isSystemApp */));
1430
1431 runWebViewBootPreparationOnMainSync();
1432 checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
1433
1434 mTestSystemImpl.setMultiProcessSetting(null /* context */, settingValue);
1435
1436 assertEquals(expectEnabled, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
1437 }
1438
1439
Gustav Sennton564c2fd2017-01-30 18:08:01 +00001440 /**
1441 * Ensure that packages with a targetSdkVersion targeting the current platform are valid, and
1442 * that packages targeting an older version are not valid.
1443 */
1444 @Test
1445 public void testTargetSdkVersionValidity() {
1446 PackageInfo newSdkPackage = createPackageInfo("newTargetSdkPackage",
1447 true /* enabled */, true /* valid */, true /* installed */);
1448 newSdkPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1449 PackageInfo currentSdkPackage = createPackageInfo("currentTargetSdkPackage",
1450 true /* enabled */, true /* valid */, true /* installed */);
Gustav Senntone5468f72017-11-20 19:42:43 +00001451 currentSdkPackage.applicationInfo.targetSdkVersion = UserPackage.MINIMUM_SUPPORTED_SDK;
Gustav Sennton564c2fd2017-01-30 18:08:01 +00001452 PackageInfo oldSdkPackage = createPackageInfo("oldTargetSdkPackage",
1453 true /* enabled */, true /* valid */, true /* installed */);
Gustav Senntone5468f72017-11-20 19:42:43 +00001454 oldSdkPackage.applicationInfo.targetSdkVersion = UserPackage.MINIMUM_SUPPORTED_SDK - 1;
Gustav Sennton564c2fd2017-01-30 18:08:01 +00001455
1456 WebViewProviderInfo newSdkProviderInfo =
1457 new WebViewProviderInfo(newSdkPackage.packageName, "", true, false, null);
1458 WebViewProviderInfo currentSdkProviderInfo =
1459 new WebViewProviderInfo(currentSdkPackage.packageName, "", true, false, null);
1460 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1461 new WebViewProviderInfo(oldSdkPackage.packageName, "", true, false, null),
1462 currentSdkProviderInfo, newSdkProviderInfo};
Torne (Richard Coles)ef478902019-03-28 15:03:21 -04001463 setupWithPackages(packages);
Gustav Sennton564c2fd2017-01-30 18:08:01 +00001464;
1465 mTestSystemImpl.setPackageInfo(newSdkPackage);
1466 mTestSystemImpl.setPackageInfo(currentSdkPackage);
1467 mTestSystemImpl.setPackageInfo(oldSdkPackage);
1468
1469 assertArrayEquals(new WebViewProviderInfo[]{currentSdkProviderInfo, newSdkProviderInfo},
1470 mWebViewUpdateServiceImpl.getValidWebViewPackages());
1471
1472 runWebViewBootPreparationOnMainSync();
1473
1474 checkPreparationPhasesForPackage(currentSdkPackage.packageName,
1475 1 /* first preparation phase */);
1476 }
Gustav Sennton53b78242016-04-07 15:56:10 +01001477}