blob: 401f585886a235eaf45050b40fb86c2bffd6b0a0 [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;
Torne (Richard Coles)dc375072017-01-11 15:48:13 +000022import static org.junit.Assert.assertTrue;
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010023
Gustav Sennton53b78242016-04-07 15:56:10 +010024import android.content.Context;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.PackageInfo;
27import android.content.pm.Signature;
Gustav Sennton564c2fd2017-01-30 18:08:01 +000028import android.os.Build;
Gustav Sennton53b78242016-04-07 15:56:10 +010029import android.os.Bundle;
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010030import android.support.test.InstrumentationRegistry;
31import android.support.test.runner.AndroidJUnit4;
Gustav Sennton148cb3e2016-09-02 15:58:38 +010032import android.test.suitebuilder.annotation.MediumTest;
Gustav Sennton53b78242016-04-07 15:56:10 +010033import android.util.Base64;
Gustav Senntone5468f72017-11-20 19:42:43 +000034import android.webkit.UserPackage;
Gustav Sennton53b78242016-04-07 15:56:10 +010035import android.webkit.WebViewFactory;
36import android.webkit.WebViewProviderInfo;
37import android.webkit.WebViewProviderResponse;
38
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010039import org.junit.Test;
40import org.junit.runner.RunWith;
41
Gustav Sennton53b78242016-04-07 15:56:10 +010042import org.mockito.Mockito;
43import org.mockito.Matchers;
Paul Duffin192bb0b2017-03-09 18:49:41 +000044import org.mockito.compat.ArgumentMatcher;
Gustav Sennton53b78242016-04-07 15:56:10 +010045
Gustav Senntonb2650162017-04-07 14:41:38 +010046import java.lang.Integer;
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010047import java.util.concurrent.CountDownLatch;
48
Gustav Sennton53b78242016-04-07 15:56:10 +010049
50/**
51 * Tests for WebViewUpdateService
Gustav Sennton148cb3e2016-09-02 15:58:38 +010052 runtest --path frameworks/base/services/tests/servicestests/ \
53 -c com.android.server.webkit.WebViewUpdateServiceTest
Gustav Sennton53b78242016-04-07 15:56:10 +010054 */
Gustav Sennton148cb3e2016-09-02 15:58:38 +010055// Use MediumTest instead of SmallTest as the implementation of WebViewUpdateService
56// is intended to work on several threads and uses at least one sleep/wait-statement.
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010057@RunWith(AndroidJUnit4.class)
Gustav Sennton148cb3e2016-09-02 15:58:38 +010058@MediumTest
Gustav Sennton86f7bbe2016-10-24 16:49:32 +010059public class WebViewUpdateServiceTest {
Gustav Sennton53b78242016-04-07 15:56:10 +010060 private final static String TAG = WebViewUpdateServiceTest.class.getSimpleName();
61
62 private WebViewUpdateServiceImpl mWebViewUpdateServiceImpl;
63 private TestSystemImpl mTestSystemImpl;
64
65 private static final String WEBVIEW_LIBRARY_FLAG = "com.android.webview.WebViewLibrary";
66
Gustav Sennton53b78242016-04-07 15:56:10 +010067 /**
68 * Creates a new instance.
69 */
70 public WebViewUpdateServiceTest() {
71 }
72
73 private void setupWithPackages(WebViewProviderInfo[] packages) {
74 setupWithPackages(packages, true);
75 }
76
77 private void setupWithPackages(WebViewProviderInfo[] packages,
78 boolean fallbackLogicEnabled) {
79 setupWithPackages(packages, fallbackLogicEnabled, 1);
80 }
81
82 private void setupWithPackages(WebViewProviderInfo[] packages,
83 boolean fallbackLogicEnabled, int numRelros) {
84 setupWithPackages(packages, fallbackLogicEnabled, numRelros,
85 true /* isDebuggable == true -> don't check package signatures */);
86 }
87
88 private void setupWithPackages(WebViewProviderInfo[] packages,
89 boolean fallbackLogicEnabled, int numRelros, boolean isDebuggable) {
Torne (Richard Coles)dc375072017-01-11 15:48:13 +000090 setupWithPackages(packages, fallbackLogicEnabled, numRelros, isDebuggable,
91 false /* multiProcessDefault */);
92 }
93
94 private void setupWithPackages(WebViewProviderInfo[] packages,
95 boolean fallbackLogicEnabled, int numRelros, boolean isDebuggable,
96 boolean multiProcessDefault) {
Gustav Sennton53b78242016-04-07 15:56:10 +010097 TestSystemImpl testing = new TestSystemImpl(packages, fallbackLogicEnabled, numRelros,
Torne (Richard Coles)dc375072017-01-11 15:48:13 +000098 isDebuggable, multiProcessDefault);
Gustav Sennton53b78242016-04-07 15:56:10 +010099 mTestSystemImpl = Mockito.spy(testing);
100 mWebViewUpdateServiceImpl =
101 new WebViewUpdateServiceImpl(null /*Context*/, mTestSystemImpl);
102 }
103
104 private void setEnabledAndValidPackageInfos(WebViewProviderInfo[] providers) {
Gustav Sennton364e1602016-12-14 09:10:50 +0000105 // Set package infos for the primary user (user 0).
106 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, providers);
107 }
108
109 private void setEnabledAndValidPackageInfosForUser(int userId,
110 WebViewProviderInfo[] providers) {
Gustav Sennton53b78242016-04-07 15:56:10 +0100111 for(WebViewProviderInfo wpi : providers) {
Gustav Sennton364e1602016-12-14 09:10:50 +0000112 mTestSystemImpl.setPackageInfoForUser(userId, createPackageInfo(wpi.packageName,
113 true /* enabled */, true /* valid */, true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100114 }
115 }
116
Gustav Senntona9159042016-04-11 16:32:52 +0100117 private void checkCertainPackageUsedAfterWebViewBootPreparation(String expectedProviderName,
Gustav Sennton53b78242016-04-07 15:56:10 +0100118 WebViewProviderInfo[] webviewPackages) {
Gustav Senntona9159042016-04-11 16:32:52 +0100119 checkCertainPackageUsedAfterWebViewBootPreparation(
120 expectedProviderName, webviewPackages, 1);
Gustav Sennton53b78242016-04-07 15:56:10 +0100121 }
122
Gustav Senntona9159042016-04-11 16:32:52 +0100123 private void checkCertainPackageUsedAfterWebViewBootPreparation(String expectedProviderName,
Gustav Sennton53b78242016-04-07 15:56:10 +0100124 WebViewProviderInfo[] webviewPackages, int numRelros) {
125 setupWithPackages(webviewPackages, true, numRelros);
126 // Add (enabled and valid) package infos for each provider
127 setEnabledAndValidPackageInfos(webviewPackages);
128
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100129 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100130
131 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
132 Mockito.argThat(new IsPackageInfoWithName(expectedProviderName)));
133
134 for (int n = 0; n < numRelros; n++) {
135 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
136 }
137
138 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
139 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, response.status);
140 assertEquals(expectedProviderName, response.packageInfo.packageName);
141 }
142
143 // For matching the package name of a PackageInfo
144 private class IsPackageInfoWithName extends ArgumentMatcher<PackageInfo> {
145 private final String mPackageName;
146
147 IsPackageInfoWithName(String name) {
148 mPackageName = name;
149 }
150
151 @Override
Paul Duffin192bb0b2017-03-09 18:49:41 +0000152 public boolean matchesObject(Object p) {
Gustav Sennton53b78242016-04-07 15:56:10 +0100153 return ((PackageInfo) p).packageName.equals(mPackageName);
154 }
155
Gustav Sennton53b78242016-04-07 15:56:10 +0100156 @Override
Paul Duffin192bb0b2017-03-09 18:49:41 +0000157 public String toString() {
158 return String.format("PackageInfo with name '%s'", mPackageName);
Gustav Sennton53b78242016-04-07 15:56:10 +0100159 }
160 }
161
162 private static PackageInfo createPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100163 String packageName, boolean enabled, boolean valid, boolean installed) {
Gustav Sennton53b78242016-04-07 15:56:10 +0100164 PackageInfo p = new PackageInfo();
165 p.packageName = packageName;
166 p.applicationInfo = new ApplicationInfo();
167 p.applicationInfo.enabled = enabled;
168 p.applicationInfo.metaData = new Bundle();
Gustav Sennton0df2c552016-06-14 15:32:19 +0100169 if (installed) {
170 p.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
171 } else {
172 p.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
173 }
Gustav Sennton53b78242016-04-07 15:56:10 +0100174 if (valid) {
175 // no flag means invalid
176 p.applicationInfo.metaData.putString(WEBVIEW_LIBRARY_FLAG, "blah");
177 }
Gustav Sennton564c2fd2017-01-30 18:08:01 +0000178 // Default to this package being valid in terms of targetSdkVersion.
179 p.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
Gustav Sennton53b78242016-04-07 15:56:10 +0100180 return p;
181 }
182
Gustav Sennton0df2c552016-06-14 15:32:19 +0100183 private static PackageInfo createPackageInfo(String packageName, boolean enabled, boolean valid,
184 boolean installed, Signature[] signatures, long updateTime) {
185 PackageInfo p = createPackageInfo(packageName, enabled, valid, installed);
Gustav Sennton53b78242016-04-07 15:56:10 +0100186 p.signatures = signatures;
Gustav Sennton0df2c552016-06-14 15:32:19 +0100187 p.lastUpdateTime = updateTime;
Gustav Sennton53b78242016-04-07 15:56:10 +0100188 return p;
189 }
190
Gustav Sennton18c9e152016-04-15 15:24:53 +0100191 private static PackageInfo createPackageInfo(String packageName, boolean enabled, boolean valid,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100192 boolean installed, Signature[] signatures, long updateTime, boolean hidden) {
193 PackageInfo p =
194 createPackageInfo(packageName, enabled, valid, installed, signatures, updateTime);
195 if (hidden) {
196 p.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
197 } else {
198 p.applicationInfo.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_HIDDEN;
199 }
Gustav Sennton53b78242016-04-07 15:56:10 +0100200 return p;
201 }
202
Gustav Senntonfd222fc22016-06-16 20:24:23 +0100203 private static PackageInfo createPackageInfo(String packageName, boolean enabled, boolean valid,
204 boolean installed, Signature[] signatures, long updateTime, boolean hidden,
205 int versionCode, boolean isSystemApp) {
206 PackageInfo p = createPackageInfo(packageName, enabled, valid, installed, signatures,
207 updateTime, hidden);
Gustav Sennton18c9e152016-04-15 15:24:53 +0100208 p.versionCode = versionCode;
209 p.applicationInfo.versionCode = versionCode;
210 if (isSystemApp) p.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
211 return p;
212 }
213
Gustav Senntona9159042016-04-11 16:32:52 +0100214 private void checkPreparationPhasesForPackage(String expectedPackage, int numPreparation) {
215 // Verify that onWebViewProviderChanged was called for the numPreparation'th time for the
216 // expected package
217 Mockito.verify(mTestSystemImpl, Mockito.times(numPreparation)).onWebViewProviderChanged(
218 Mockito.argThat(new IsPackageInfoWithName(expectedPackage)));
219
220 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
221
222 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
223 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, response.status);
224 assertEquals(expectedPackage, response.packageInfo.packageName);
225 }
226
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100227 /**
228 * The WebView preparation boot phase is run on the main thread (especially on a thread with a
229 * looper) so to avoid bugs where our tests fail because a looper hasn't been attached to the
230 * thread running prepareWebViewInSystemServer we run it on the main thread.
231 */
232 private void runWebViewBootPreparationOnMainSync() {
233 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
234 @Override
235 public void run() {
236 mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
237 }
238 });
239 }
240
Gustav Sennton53b78242016-04-07 15:56:10 +0100241
242 // ****************
243 // Tests
244 // ****************
245
246
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100247 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100248 public void testWithSinglePackage() {
249 String testPackageName = "test.package.name";
Gustav Senntona9159042016-04-11 16:32:52 +0100250 checkCertainPackageUsedAfterWebViewBootPreparation(testPackageName,
Gustav Sennton53b78242016-04-07 15:56:10 +0100251 new WebViewProviderInfo[] {
252 new WebViewProviderInfo(testPackageName, "",
253 true /*default available*/, false /* fallback */, null)});
254 }
255
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100256 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100257 public void testDefaultPackageUsedOverNonDefault() {
258 String defaultPackage = "defaultPackage";
259 String nonDefaultPackage = "nonDefaultPackage";
260 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
261 new WebViewProviderInfo(nonDefaultPackage, "", false, false, null),
262 new WebViewProviderInfo(defaultPackage, "", true, false, null)};
Gustav Senntona9159042016-04-11 16:32:52 +0100263 checkCertainPackageUsedAfterWebViewBootPreparation(defaultPackage, packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100264 }
265
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100266 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100267 public void testSeveralRelros() {
268 String singlePackage = "singlePackage";
Gustav Senntona9159042016-04-11 16:32:52 +0100269 checkCertainPackageUsedAfterWebViewBootPreparation(
Gustav Sennton53b78242016-04-07 15:56:10 +0100270 singlePackage,
271 new WebViewProviderInfo[] {
272 new WebViewProviderInfo(singlePackage, "", true /*def av*/, false, null)},
273 2);
274 }
275
276 // Ensure that package with valid signatures is chosen rather than package with invalid
277 // signatures.
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100278 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100279 public void testWithSignatures() {
280 String validPackage = "valid package";
281 String invalidPackage = "invalid package";
282
283 Signature validSignature = new Signature("11");
284 Signature invalidExpectedSignature = new Signature("22");
285 Signature invalidPackageSignature = new Signature("33");
286
287 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
288 new WebViewProviderInfo(invalidPackage, "", true, false, new String[]{
289 Base64.encodeToString(
290 invalidExpectedSignature.toByteArray(), Base64.DEFAULT)}),
291 new WebViewProviderInfo(validPackage, "", true, false, new String[]{
292 Base64.encodeToString(
293 validSignature.toByteArray(), Base64.DEFAULT)})
294 };
295 setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
296 false /* isDebuggable */);
297 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
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100516 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100517 public void testRunFallbackLogicIfEnabled() {
518 checkFallbackLogicBeingRun(true);
519 }
520
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100521 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100522 public void testDontRunFallbackLogicIfDisabled() {
523 checkFallbackLogicBeingRun(false);
524 }
525
526 private void checkFallbackLogicBeingRun(boolean fallbackLogicEnabled) {
527 String primaryPackage = "primary";
528 String fallbackPackage = "fallback";
529 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
530 new WebViewProviderInfo(
531 primaryPackage, "", true /* default available */, false /* fallback */, null),
532 new WebViewProviderInfo(
533 fallbackPackage, "", true /* default available */, true /* fallback */, null)};
534 setupWithPackages(packages, fallbackLogicEnabled);
535 setEnabledAndValidPackageInfos(packages);
536
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100537 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100538 // Verify that we disable the fallback package if fallback logic enabled, and don't disable
539 // the fallback package if that logic is disabled
540 if (fallbackLogicEnabled) {
541 Mockito.verify(mTestSystemImpl).uninstallAndDisablePackageForAllUsers(
542 Matchers.anyObject(), Mockito.eq(fallbackPackage));
543 } else {
544 Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
545 Matchers.anyObject(), Matchers.anyObject());
546 }
547 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
548 Mockito.argThat(new IsPackageInfoWithName(primaryPackage)));
549
550 // Enable fallback package
551 mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100552 true /* valid */, true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100553 mWebViewUpdateServiceImpl.packageStateChanged(
Gustav Sennton364e1602016-12-14 09:10:50 +0000554 fallbackPackage, WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton53b78242016-04-07 15:56:10 +0100555
556 if (fallbackLogicEnabled) {
557 // Check that we have now disabled the fallback package twice
558 Mockito.verify(mTestSystemImpl, Mockito.times(2)).uninstallAndDisablePackageForAllUsers(
559 Matchers.anyObject(), Mockito.eq(fallbackPackage));
560 } else {
561 // Check that we still haven't disabled any package
562 Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
563 Matchers.anyObject(), Matchers.anyObject());
564 }
565 }
566
567 /**
568 * Scenario for installing primary package when fallback enabled.
569 * 1. Start with only fallback installed
570 * 2. Install non-fallback
571 * 3. Fallback should be disabled
572 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100573 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100574 public void testInstallingNonFallbackPackage() {
575 String primaryPackage = "primary";
576 String fallbackPackage = "fallback";
577 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
578 new WebViewProviderInfo(
579 primaryPackage, "", true /* default available */, false /* fallback */, null),
580 new WebViewProviderInfo(
581 fallbackPackage, "", true /* default available */, true /* fallback */, null)};
582 setupWithPackages(packages, true /* isFallbackLogicEnabled */);
583 mTestSystemImpl.setPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100584 createPackageInfo(fallbackPackage, true /* enabled */ , true /* valid */,
585 true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100586
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100587 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100588 Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
589 Matchers.anyObject(), Matchers.anyObject());
Gustav Sennton53b78242016-04-07 15:56:10 +0100590
Gustav Senntona9159042016-04-11 16:32:52 +0100591 checkPreparationPhasesForPackage(fallbackPackage,
592 1 /* first preparation for this package*/);
Gustav Sennton53b78242016-04-07 15:56:10 +0100593
594 // Install primary package
595 mTestSystemImpl.setPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100596 createPackageInfo(primaryPackage, true /* enabled */ , true /* valid */,
597 true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100598 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000599 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton53b78242016-04-07 15:56:10 +0100600
Gustav Senntona9159042016-04-11 16:32:52 +0100601 // Verify fallback disabled, primary package used as provider, and fallback package killed
Gustav Sennton53b78242016-04-07 15:56:10 +0100602 Mockito.verify(mTestSystemImpl).uninstallAndDisablePackageForAllUsers(
603 Matchers.anyObject(), Mockito.eq(fallbackPackage));
Gustav Senntona9159042016-04-11 16:32:52 +0100604 checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation for this package*/);
Gustav Sennton53b78242016-04-07 15:56:10 +0100605 Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(fallbackPackage));
606 }
607
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100608 @Test
Gustav Sennton364e1602016-12-14 09:10:50 +0000609 public void testFallbackChangesEnabledStateSingleUser() {
610 for (PackageRemovalType removalType : REMOVAL_TYPES) {
611 checkFallbackChangesEnabledState(false /* multiUser */, removalType);
612 }
613 }
614
615 @Test
616 public void testFallbackChangesEnabledStateMultiUser() {
617 for (PackageRemovalType removalType : REMOVAL_TYPES) {
618 checkFallbackChangesEnabledState(true /* multiUser */, removalType);
619 }
620 }
621
622 /**
623 * Represents how to remove a package during a tests (disabling it / uninstalling it / hiding
624 * it).
625 */
626 private enum PackageRemovalType {
627 UNINSTALL, DISABLE, HIDE
628 }
629
630 private PackageRemovalType[] REMOVAL_TYPES = PackageRemovalType.class.getEnumConstants();
631
632 public void checkFallbackChangesEnabledState(boolean multiUser,
633 PackageRemovalType removalType) {
Gustav Sennton53b78242016-04-07 15:56:10 +0100634 String primaryPackage = "primary";
635 String fallbackPackage = "fallback";
636 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
637 new WebViewProviderInfo(
638 primaryPackage, "", true /* default available */, false /* fallback */, null),
639 new WebViewProviderInfo(
640 fallbackPackage, "", true /* default available */, true /* fallback */, null)};
641 setupWithPackages(packages, true /* fallbackLogicEnabled */);
Gustav Sennton364e1602016-12-14 09:10:50 +0000642 int secondaryUserId = 10;
643 int userIdToChangePackageFor = multiUser ? secondaryUserId : TestSystemImpl.PRIMARY_USER_ID;
644 if (multiUser) {
645 mTestSystemImpl.addUser(secondaryUserId);
646 setEnabledAndValidPackageInfosForUser(secondaryUserId, packages);
647 }
648 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100649
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100650 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100651
652 // Verify fallback disabled at boot when primary package enabled
Gustav Sennton364e1602016-12-14 09:10:50 +0000653 checkEnablePackageForUserCalled(fallbackPackage, false, multiUser
654 ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
655 : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */);
Gustav Sennton53b78242016-04-07 15:56:10 +0100656
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100657 checkPreparationPhasesForPackage(primaryPackage, 1);
658
Gustav Sennton364e1602016-12-14 09:10:50 +0000659 boolean enabled = !(removalType == PackageRemovalType.DISABLE);
660 boolean installed = !(removalType == PackageRemovalType.UNINSTALL);
661 boolean hidden = (removalType == PackageRemovalType.HIDE);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100662 // Disable primary package and ensure fallback becomes enabled and used
Gustav Sennton364e1602016-12-14 09:10:50 +0000663 mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
664 createPackageInfo(primaryPackage, enabled /* enabled */, true /* valid */,
665 installed /* installed */, null /* signature */, 0 /* updateTime */,
666 hidden /* hidden */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100667 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000668 removalType == PackageRemovalType.DISABLE
669 ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_REMOVED,
670 userIdToChangePackageFor); // USER ID
Gustav Sennton53b78242016-04-07 15:56:10 +0100671
Gustav Sennton364e1602016-12-14 09:10:50 +0000672 checkEnablePackageForUserCalled(fallbackPackage, true, multiUser
673 ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
674 : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */);
Gustav Sennton53b78242016-04-07 15:56:10 +0100675
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100676 checkPreparationPhasesForPackage(fallbackPackage, 1);
677
678
679 // Again enable primary package and verify primary is used and fallback becomes disabled
Gustav Sennton364e1602016-12-14 09:10:50 +0000680 mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100681 createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
682 true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100683 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000684 removalType == PackageRemovalType.DISABLE
685 ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_ADDED,
686 userIdToChangePackageFor);
Gustav Sennton53b78242016-04-07 15:56:10 +0100687
688 // Verify fallback is disabled a second time when primary package becomes enabled
Gustav Sennton364e1602016-12-14 09:10:50 +0000689 checkEnablePackageForUserCalled(fallbackPackage, false, multiUser
690 ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
691 : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 2 /* numUsages */);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100692
693 checkPreparationPhasesForPackage(primaryPackage, 2);
Gustav Sennton53b78242016-04-07 15:56:10 +0100694 }
695
Gustav Sennton364e1602016-12-14 09:10:50 +0000696 private void checkEnablePackageForUserCalled(String packageName, boolean expectEnabled,
697 int[] userIds, int numUsages) {
698 for (int userId : userIds) {
699 Mockito.verify(mTestSystemImpl, Mockito.times(numUsages)).enablePackageForUser(
700 Mockito.eq(packageName), Mockito.eq(expectEnabled), Mockito.eq(userId));
701 }
702 }
703
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100704 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100705 public void testAddUserWhenFallbackLogicEnabled() {
706 checkAddingNewUser(true);
707 }
708
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100709 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100710 public void testAddUserWhenFallbackLogicDisabled() {
711 checkAddingNewUser(false);
712 }
713
714 public void checkAddingNewUser(boolean fallbackLogicEnabled) {
715 String primaryPackage = "primary";
716 String fallbackPackage = "fallback";
717 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
718 new WebViewProviderInfo(
719 primaryPackage, "", true /* default available */, false /* fallback */, null),
720 new WebViewProviderInfo(
721 fallbackPackage, "", true /* default available */, true /* fallback */, null)};
722 setupWithPackages(packages, fallbackLogicEnabled);
Gustav Sennton364e1602016-12-14 09:10:50 +0000723 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100724 int newUser = 100;
Gustav Sennton364e1602016-12-14 09:10:50 +0000725 mTestSystemImpl.addUser(newUser);
726 setEnabledAndValidPackageInfosForUser(newUser, packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100727 mWebViewUpdateServiceImpl.handleNewUser(newUser);
728 if (fallbackLogicEnabled) {
729 // Verify fallback package becomes disabled for new user
730 Mockito.verify(mTestSystemImpl).enablePackageForUser(
731 Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
732 Mockito.eq(newUser));
733 } else {
734 // Verify that we don't disable fallback for new user
735 Mockito.verify(mTestSystemImpl, Mockito.never()).enablePackageForUser(
736 Mockito.anyObject(), Matchers.anyBoolean() /* enable */,
737 Matchers.anyInt() /* user */);
738 }
739 }
740
741 /**
Gustav Sennton364e1602016-12-14 09:10:50 +0000742 * Ensures that adding a new user for which the current WebView package is uninstalled causes a
743 * change of WebView provider.
744 */
745 @Test
746 public void testAddingNewUserWithUninstalledPackage() {
747 String primaryPackage = "primary";
748 String fallbackPackage = "fallback";
749 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
750 new WebViewProviderInfo(
751 primaryPackage, "", true /* default available */, false /* fallback */, null),
752 new WebViewProviderInfo(
753 fallbackPackage, "", true /* default available */, true /* fallback */, null)};
754 setupWithPackages(packages, true /* fallbackLogicEnabled */);
755 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
756 int newUser = 100;
757 mTestSystemImpl.addUser(newUser);
758 // Let the primary package be uninstalled for the new user
759 mTestSystemImpl.setPackageInfoForUser(newUser,
760 createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
761 false /* installed */));
762 mTestSystemImpl.setPackageInfoForUser(newUser,
763 createPackageInfo(fallbackPackage, false /* enabled */, true /* valid */,
764 true /* installed */));
765 mWebViewUpdateServiceImpl.handleNewUser(newUser);
766 // Verify fallback package doesn't become disabled for the primary user.
767 Mockito.verify(mTestSystemImpl, Mockito.never()).enablePackageForUser(
768 Mockito.anyObject(), Mockito.eq(false) /* enable */,
769 Mockito.eq(TestSystemImpl.PRIMARY_USER_ID) /* user */);
770 // Verify that we enable the fallback package for the secondary user.
771 Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
772 Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */,
773 Mockito.eq(newUser) /* user */);
774 checkPreparationPhasesForPackage(fallbackPackage, 1 /* numRelros */);
775 }
776
777 /**
Gustav Sennton53b78242016-04-07 15:56:10 +0100778 * Timing dependent test where we verify that the list of valid webview packages becoming empty
779 * at a certain point doesn't crash us or break our state.
780 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100781 @Test
Gustav Sennton53b78242016-04-07 15:56:10 +0100782 public void testNotifyRelroDoesntCrashIfNoPackages() {
783 String firstPackage = "first";
784 String secondPackage = "second";
785 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
786 new WebViewProviderInfo(firstPackage, "", true /* default available */,
787 false /* fallback */, null),
788 new WebViewProviderInfo(secondPackage, "", true /* default available */,
789 false /* fallback */, null)};
790 setupWithPackages(packages);
791 // Add (enabled and valid) package infos for each provider
792 setEnabledAndValidPackageInfos(packages);
793
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100794 runWebViewBootPreparationOnMainSync();
Gustav Sennton53b78242016-04-07 15:56:10 +0100795
796 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
797 Mockito.argThat(new IsPackageInfoWithName(firstPackage)));
798
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100799 // Change provider during relro creation to enter a state where we are
800 // waiting for relro creation to complete just to re-run relro creation.
801 // (so that in next notifyRelroCreationCompleted() call we have to list webview packages)
Gustav Sennton53b78242016-04-07 15:56:10 +0100802 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
803
804 // Make packages invalid to cause exception to be thrown
805 mTestSystemImpl.setPackageInfo(createPackageInfo(firstPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100806 false /* valid */, true /* installed */, null /* signatures */,
807 0 /* updateTime */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100808 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100809 false /* valid */, true /* installed */));
Gustav Sennton53b78242016-04-07 15:56:10 +0100810
811 // This shouldn't throw an exception!
812 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
813
814 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
815 assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
816
817 // Now make a package valid again and verify that we can switch back to that
818 mTestSystemImpl.setPackageInfo(createPackageInfo(firstPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100819 true /* valid */, true /* installed */, null /* signatures */,
820 1 /* updateTime */ ));
Gustav Sennton53b78242016-04-07 15:56:10 +0100821
822 mWebViewUpdateServiceImpl.packageStateChanged(firstPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000823 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton53b78242016-04-07 15:56:10 +0100824
Gustav Senntona9159042016-04-11 16:32:52 +0100825 // Ensure we use firstPackage
826 checkPreparationPhasesForPackage(firstPackage, 2 /* second preparation for this package */);
827 }
Gustav Sennton53b78242016-04-07 15:56:10 +0100828
Gustav Senntona9159042016-04-11 16:32:52 +0100829 /**
830 * Verify that even if a user-chosen package is removed temporarily we start using it again when
831 * it is added back.
832 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100833 @Test
Gustav Senntona9159042016-04-11 16:32:52 +0100834 public void testTempRemovePackageDoesntSwitchProviderPermanently() {
835 String firstPackage = "first";
836 String secondPackage = "second";
837 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
838 new WebViewProviderInfo(firstPackage, "", true /* default available */,
839 false /* fallback */, null),
840 new WebViewProviderInfo(secondPackage, "", true /* default available */,
841 false /* fallback */, null)};
842 checkCertainPackageUsedAfterWebViewBootPreparation(firstPackage, packages);
Gustav Sennton53b78242016-04-07 15:56:10 +0100843
Gustav Senntona9159042016-04-11 16:32:52 +0100844 // Explicitly use the second package
845 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
846 checkPreparationPhasesForPackage(secondPackage, 1 /* first time for this package */);
847
848 // Remove second package (invalidate it) and verify that first package is used
849 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100850 false /* valid */, true /* installed */));
Gustav Senntona9159042016-04-11 16:32:52 +0100851 mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000852 WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Senntona9159042016-04-11 16:32:52 +0100853 checkPreparationPhasesForPackage(firstPackage, 2 /* second time for this package */);
854
855 // Now make the second package valid again and verify that it is used again
856 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100857 true /* valid */, true /* installed */));
Gustav Senntona9159042016-04-11 16:32:52 +0100858 mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000859 WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Senntona9159042016-04-11 16:32:52 +0100860 checkPreparationPhasesForPackage(secondPackage, 2 /* second time for this package */);
861 }
862
863 /**
864 * Ensure that we update the user-chosen setting across boots if the chosen package is no
865 * longer installed and valid.
866 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100867 @Test
Gustav Senntona9159042016-04-11 16:32:52 +0100868 public void testProviderSettingChangedDuringBootIfProviderNotAvailable() {
869 String chosenPackage = "chosenPackage";
870 String nonChosenPackage = "non-chosenPackage";
871 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
872 new WebViewProviderInfo(chosenPackage, "", true /* default available */,
873 false /* fallback */, null),
874 new WebViewProviderInfo(nonChosenPackage, "", true /* default available */,
875 false /* fallback */, null)};
876
877 setupWithPackages(packages);
878 // Only 'install' nonChosenPackage
879 mTestSystemImpl.setPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100880 createPackageInfo(nonChosenPackage, true /* enabled */, true /* valid */, true /* installed */));
Gustav Senntona9159042016-04-11 16:32:52 +0100881
882 // Set user-chosen package
883 mTestSystemImpl.updateUserSetting(null, chosenPackage);
884
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100885 runWebViewBootPreparationOnMainSync();
Gustav Senntona9159042016-04-11 16:32:52 +0100886
887 // Verify that we switch the setting to point to the current package
888 Mockito.verify(mTestSystemImpl).updateUserSetting(
889 Mockito.anyObject(), Mockito.eq(nonChosenPackage));
890 assertEquals(nonChosenPackage, mTestSystemImpl.getUserChosenWebViewProvider(null));
891
892 checkPreparationPhasesForPackage(nonChosenPackage, 1);
Gustav Sennton53b78242016-04-07 15:56:10 +0100893 }
894
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100895 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100896 public void testRecoverFailedListingWebViewPackagesSettingsChange() {
897 checkRecoverAfterFailListingWebviewPackages(true);
898 }
899
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100900 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100901 public void testRecoverFailedListingWebViewPackagesAddedPackage() {
902 checkRecoverAfterFailListingWebviewPackages(false);
903 }
904
905 /**
906 * Test that we can recover correctly from failing to list WebView packages.
907 * settingsChange: whether to fail during changeProviderAndSetting or packageStateChanged
908 */
909 public void checkRecoverAfterFailListingWebviewPackages(boolean settingsChange) {
910 String firstPackage = "first";
911 String secondPackage = "second";
912 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
913 new WebViewProviderInfo(firstPackage, "", true /* default available */,
914 false /* fallback */, null),
915 new WebViewProviderInfo(secondPackage, "", true /* default available */,
916 false /* fallback */, null)};
917 checkCertainPackageUsedAfterWebViewBootPreparation(firstPackage, packages);
918
919 // Make both packages invalid so that we fail listing WebView packages
920 mTestSystemImpl.setPackageInfo(createPackageInfo(firstPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100921 false /* valid */, true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100922 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100923 false /* valid */, true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100924
925 // Change package to hit the webview packages listing problem.
926 if (settingsChange) {
927 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
928 } else {
929 mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000930 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100931 }
932
933 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
934 assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
935
936 // Make second package valid and verify that we can load it again
937 mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +0100938 true /* valid */, true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100939
940 mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000941 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100942
943
944 checkPreparationPhasesForPackage(secondPackage, 1);
945 }
946
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100947 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100948 public void testDontKillIfPackageReplaced() {
949 checkDontKillIfPackageRemoved(true);
950 }
951
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100952 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100953 public void testDontKillIfPackageRemoved() {
954 checkDontKillIfPackageRemoved(false);
955 }
956
957 public void checkDontKillIfPackageRemoved(boolean replaced) {
958 String firstPackage = "first";
959 String secondPackage = "second";
960 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
961 new WebViewProviderInfo(firstPackage, "", true /* default available */,
962 false /* fallback */, null),
963 new WebViewProviderInfo(secondPackage, "", true /* default available */,
964 false /* fallback */, null)};
965 checkCertainPackageUsedAfterWebViewBootPreparation(firstPackage, packages);
966
967 // Replace or remove the current webview package
968 if (replaced) {
969 mTestSystemImpl.setPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +0100970 createPackageInfo(firstPackage, true /* enabled */, false /* valid */,
971 true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100972 mWebViewUpdateServiceImpl.packageStateChanged(firstPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000973 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100974 } else {
975 mTestSystemImpl.removePackageInfo(firstPackage);
976 mWebViewUpdateServiceImpl.packageStateChanged(firstPackage,
Gustav Sennton364e1602016-12-14 09:10:50 +0000977 WebViewUpdateService.PACKAGE_REMOVED, TestSystemImpl.PRIMARY_USER_ID);
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100978 }
979
980 checkPreparationPhasesForPackage(secondPackage, 1);
981
982 Mockito.verify(mTestSystemImpl, Mockito.never()).killPackageDependents(
983 Mockito.anyObject());
984 }
985
Gustav Sennton86f7bbe2016-10-24 16:49:32 +0100986 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +0100987 public void testKillIfSettingChanged() {
988 String firstPackage = "first";
989 String secondPackage = "second";
990 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
991 new WebViewProviderInfo(firstPackage, "", true /* default available */,
992 false /* fallback */, null),
993 new WebViewProviderInfo(secondPackage, "", true /* default available */,
994 false /* fallback */, null)};
995 checkCertainPackageUsedAfterWebViewBootPreparation(firstPackage, packages);
996
997 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
998
999 checkPreparationPhasesForPackage(secondPackage, 1);
1000
1001 Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(firstPackage));
1002 }
1003
1004 /**
1005 * Test that we kill apps using an old provider when we change the provider setting, even if the
1006 * new provider is not the one we intended to change to.
1007 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001008 @Test
Gustav Sennton95f7e8e2016-04-14 15:07:09 +01001009 public void testKillIfChangeProviderIncorrectly() {
1010 String firstPackage = "first";
1011 String secondPackage = "second";
1012 String thirdPackage = "third";
1013 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1014 new WebViewProviderInfo(firstPackage, "", true /* default available */,
1015 false /* fallback */, null),
1016 new WebViewProviderInfo(secondPackage, "", true /* default available */,
1017 false /* fallback */, null),
1018 new WebViewProviderInfo(thirdPackage, "", true /* default available */,
1019 false /* fallback */, null)};
1020 setupWithPackages(packages);
1021 setEnabledAndValidPackageInfos(packages);
1022
1023 // Start with the setting pointing to the third package
1024 mTestSystemImpl.updateUserSetting(null, thirdPackage);
1025
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001026 runWebViewBootPreparationOnMainSync();
Gustav Sennton95f7e8e2016-04-14 15:07:09 +01001027 checkPreparationPhasesForPackage(thirdPackage, 1);
1028
1029 mTestSystemImpl.setPackageInfo(
Gustav Sennton0df2c552016-06-14 15:32:19 +01001030 createPackageInfo(secondPackage, true /* enabled */, false /* valid */, true /* installed */));
Gustav Sennton95f7e8e2016-04-14 15:07:09 +01001031
1032 // Try to switch to the invalid second package, this should result in switching to the first
1033 // package, since that is more preferred than the third one.
1034 assertEquals(firstPackage,
1035 mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage));
1036
1037 checkPreparationPhasesForPackage(firstPackage, 1);
1038
1039 Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(thirdPackage));
1040 }
Gustav Sennton18c9e152016-04-15 15:24:53 +01001041
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001042 @Test
Gustav Sennton18c9e152016-04-15 15:24:53 +01001043 public void testLowerPackageVersionNotValid() {
Hui Shu826a24b2016-04-26 14:53:40 -07001044 checkPackageVersions(new int[]{200000} /* system version */, 100000/* candidate version */,
1045 false /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001046 }
1047
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001048 @Test
Gustav Sennton18c9e152016-04-15 15:24:53 +01001049 public void testEqualPackageVersionValid() {
Hui Shu826a24b2016-04-26 14:53:40 -07001050 checkPackageVersions(new int[]{100000} /* system version */, 100000 /* candidate version */,
1051 true /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001052 }
1053
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001054 @Test
Gustav Sennton18c9e152016-04-15 15:24:53 +01001055 public void testGreaterPackageVersionValid() {
Hui Shu826a24b2016-04-26 14:53:40 -07001056 checkPackageVersions(new int[]{100000} /* system versions */, 200000 /* candidate version */,
1057 true /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001058 }
1059
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001060 @Test
Hui Shu826a24b2016-04-26 14:53:40 -07001061 public void testLastFiveDigitsIgnored() {
1062 checkPackageVersions(new int[]{654321} /* system version */, 612345 /* candidate version */,
1063 true /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001064 }
1065
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001066 @Test
Hui Shu826a24b2016-04-26 14:53:40 -07001067 public void testMinimumSystemVersionUsedTwoDefaultsCandidateValid() {
1068 checkPackageVersions(new int[]{300000, 100000} /* system versions */,
1069 200000 /* candidate version */, true /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001070 }
1071
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001072 @Test
Hui Shu826a24b2016-04-26 14:53:40 -07001073 public void testMinimumSystemVersionUsedTwoDefaultsCandidateInvalid() {
1074 checkPackageVersions(new int[]{300000, 200000} /* system versions */,
1075 100000 /* candidate version */, false /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001076 }
1077
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001078 @Test
Hui Shu826a24b2016-04-26 14:53:40 -07001079 public void testMinimumSystemVersionUsedSeveralDefaultsCandidateValid() {
1080 checkPackageVersions(new int[]{100000, 200000, 300000, 400000, 500000} /* system versions */,
1081 100000 /* candidate version */, true /* expected validity */);
1082 }
1083
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001084 @Test
Hui Shu826a24b2016-04-26 14:53:40 -07001085 public void testMinimumSystemVersionUsedSeveralDefaultsCandidateInvalid() {
1086 checkPackageVersions(new int[]{200000, 300000, 400000, 500000, 600000} /* system versions */,
1087 100000 /* candidate version */, false /* expected validity */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001088 }
1089
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001090 @Test
Gustav Sennton18c9e152016-04-15 15:24:53 +01001091 public void testMinimumSystemVersionUsedFallbackIgnored() {
Hui Shu826a24b2016-04-26 14:53:40 -07001092 checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */,
1093 200000 /* candidate version */, false /* expected validity */, true /* add fallback */,
1094 100000 /* fallback version */, false /* expected validity of fallback */);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001095 }
1096
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001097 @Test
Hui Shu826a24b2016-04-26 14:53:40 -07001098 public void testFallbackValid() {
1099 checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */,
1100 200000/* candidate version */, false /* expected validity */, true /* add fallback */,
1101 300000 /* fallback version */, true /* expected validity of fallback */);
1102 }
1103
1104 private void checkPackageVersions(int[] systemVersions, int candidateVersion,
1105 boolean candidateShouldBeValid) {
1106 checkPackageVersions(systemVersions, candidateVersion, candidateShouldBeValid,
1107 false, 0, false);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001108 }
1109
1110 /**
1111 * Utility method for checking that package version restriction works as it should.
1112 * I.e. that a package with lower version than the system-default is not valid and that a
1113 * package with greater than or equal version code is considered valid.
1114 */
Hui Shu826a24b2016-04-26 14:53:40 -07001115 private void checkPackageVersions(int[] systemVersions, int candidateVersion,
1116 boolean candidateShouldBeValid, boolean addFallback, int fallbackVersion,
1117 boolean fallbackShouldBeValid) {
Gustav Sennton18c9e152016-04-15 15:24:53 +01001118 int numSystemPackages = systemVersions.length;
1119 int numFallbackPackages = (addFallback ? 1 : 0);
1120 int numPackages = systemVersions.length + 1 + numFallbackPackages;
Hui Shu826a24b2016-04-26 14:53:40 -07001121 String candidatePackage = "candidatePackage";
Gustav Sennton18c9e152016-04-15 15:24:53 +01001122 String systemPackage = "systemPackage";
1123 String fallbackPackage = "fallbackPackage";
1124
1125 // Each package needs a valid signature since we set isDebuggable to false
1126 Signature signature = new Signature("11");
1127 String encodedSignatureString =
1128 Base64.encodeToString(signature.toByteArray(), Base64.DEFAULT);
1129
1130 // Set up config
Hui Shu826a24b2016-04-26 14:53:40 -07001131 // 1. candidatePackage
Gustav Sennton18c9e152016-04-15 15:24:53 +01001132 // 2-N. default available non-fallback packages
1133 // N+1. default available fallback package
1134 WebViewProviderInfo[] packages = new WebViewProviderInfo[numPackages];
Hui Shu826a24b2016-04-26 14:53:40 -07001135 packages[0] = new WebViewProviderInfo(candidatePackage, "",
Gustav Sennton18c9e152016-04-15 15:24:53 +01001136 false /* available by default */, false /* fallback */,
1137 new String[]{encodedSignatureString});
1138 for(int n = 1; n < numSystemPackages + 1; n++) {
1139 packages[n] = new WebViewProviderInfo(systemPackage + n, "",
1140 true /* available by default */, false /* fallback */,
1141 new String[]{encodedSignatureString});
1142 }
1143 if (addFallback) {
1144 packages[packages.length-1] = new WebViewProviderInfo(fallbackPackage, "",
1145 true /* available by default */, true /* fallback */,
1146 new String[]{encodedSignatureString});
1147 }
1148
1149 setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
1150 false /* isDebuggable */);
1151
1152 // Set package infos
1153 mTestSystemImpl.setPackageInfo(
Hui Shu826a24b2016-04-26 14:53:40 -07001154 createPackageInfo(candidatePackage, true /* enabled */, true /* valid */,
Gustav Senntonfd222fc22016-06-16 20:24:23 +01001155 true /* installed */, new Signature[]{signature}, 0 /* updateTime */,
1156 false /* hidden */, candidateVersion, false /* isSystemApp */));
Gustav Sennton18c9e152016-04-15 15:24:53 +01001157 for(int n = 1; n < numSystemPackages + 1; n++) {
1158 mTestSystemImpl.setPackageInfo(
1159 createPackageInfo(systemPackage + n, true /* enabled */, true /* valid */,
Gustav Senntonfd222fc22016-06-16 20:24:23 +01001160 true /* installed */, new Signature[]{signature}, 0 /* updateTime */,
1161 false /* hidden */, systemVersions[n-1], true /* isSystemApp */));
Gustav Sennton18c9e152016-04-15 15:24:53 +01001162 }
1163 if (addFallback) {
1164 mTestSystemImpl.setPackageInfo(
1165 createPackageInfo(fallbackPackage, true /* enabled */, true /* valid */,
Gustav Senntonfd222fc22016-06-16 20:24:23 +01001166 true /* installed */, new Signature[]{signature}, 0 /* updateTime */,
1167 false /* hidden */, fallbackVersion, true /* isSystemApp */));
Gustav Sennton18c9e152016-04-15 15:24:53 +01001168 }
1169
1170 WebViewProviderInfo[] validPackages = mWebViewUpdateServiceImpl.getValidWebViewPackages();
Hui Shu826a24b2016-04-26 14:53:40 -07001171 int expectedNumValidPackages = numSystemPackages;
1172 if (candidateShouldBeValid) {
1173 expectedNumValidPackages++;
Gustav Sennton18c9e152016-04-15 15:24:53 +01001174 } else {
Hui Shu826a24b2016-04-26 14:53:40 -07001175 // Ensure the candidate package is not one of the valid packages
Gustav Sennton18c9e152016-04-15 15:24:53 +01001176 for(int n = 0; n < validPackages.length; n++) {
Hui Shu826a24b2016-04-26 14:53:40 -07001177 assertFalse(candidatePackage.equals(validPackages[n].packageName));
Gustav Sennton18c9e152016-04-15 15:24:53 +01001178 }
1179 }
1180
Hui Shu826a24b2016-04-26 14:53:40 -07001181 if (fallbackShouldBeValid) {
1182 expectedNumValidPackages += numFallbackPackages;
1183 } else {
1184 // Ensure the fallback package is not one of the valid packages
1185 for(int n = 0; n < validPackages.length; n++) {
1186 assertFalse(fallbackPackage.equals(validPackages[n].packageName));
1187 }
1188 }
1189
1190 assertEquals(expectedNumValidPackages, validPackages.length);
1191
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001192 runWebViewBootPreparationOnMainSync();
Gustav Sennton18c9e152016-04-15 15:24:53 +01001193
1194 // The non-system package is not available by default so it shouldn't be used here
1195 checkPreparationPhasesForPackage(systemPackage + "1", 1);
1196
Hui Shu826a24b2016-04-26 14:53:40 -07001197 // Try explicitly switching to the candidate package
1198 String packageChange = mWebViewUpdateServiceImpl.changeProviderAndSetting(candidatePackage);
1199 if (candidateShouldBeValid) {
1200 assertEquals(candidatePackage, packageChange);
1201 checkPreparationPhasesForPackage(candidatePackage, 1);
Gustav Sennton18c9e152016-04-15 15:24:53 +01001202 } else {
1203 assertEquals(systemPackage + "1", packageChange);
1204 // We didn't change package so the webview preparation won't run here
1205 }
1206 }
Gustav Senntonfd222fc22016-06-16 20:24:23 +01001207
Gustav Sennton364e1602016-12-14 09:10:50 +00001208 /**
1209 * Ensure that the update service does use an uninstalled package when that is the only
1210 * package available.
1211 */
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001212 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001213 public void testWithSingleUninstalledPackage() {
1214 String testPackageName = "test.package.name";
1215 WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
1216 new WebViewProviderInfo(testPackageName, "",
1217 true /*default available*/, false /* fallback */, null)};
1218 setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
1219 mTestSystemImpl.setPackageInfo(createPackageInfo(testPackageName, true /* enabled */,
1220 true /* valid */, false /* installed */));
1221
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001222 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001223
Gustav Sennton963dbbb2017-04-06 16:18:02 +01001224 Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
1225 Matchers.anyObject());
1226 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
1227 assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
1228 assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage());
Gustav Sennton0df2c552016-06-14 15:32:19 +01001229 }
1230
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001231 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001232 public void testNonhiddenPackageUserOverHidden() {
Gustav Sennton364e1602016-12-14 09:10:50 +00001233 checkVisiblePackageUserOverNonVisible(false /* multiUser*/, PackageRemovalType.HIDE);
1234 checkVisiblePackageUserOverNonVisible(true /* multiUser*/, PackageRemovalType.HIDE);
Gustav Sennton0df2c552016-06-14 15:32:19 +01001235 }
1236
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001237 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001238 public void testInstalledPackageUsedOverUninstalled() {
Gustav Sennton364e1602016-12-14 09:10:50 +00001239 checkVisiblePackageUserOverNonVisible(false /* multiUser*/, PackageRemovalType.UNINSTALL);
1240 checkVisiblePackageUserOverNonVisible(true /* multiUser*/, PackageRemovalType.UNINSTALL);
Gustav Sennton0df2c552016-06-14 15:32:19 +01001241 }
1242
Gustav Sennton364e1602016-12-14 09:10:50 +00001243 private void checkVisiblePackageUserOverNonVisible(boolean multiUser,
1244 PackageRemovalType removalType) {
1245 assert removalType != PackageRemovalType.DISABLE;
1246 boolean testUninstalled = removalType == PackageRemovalType.UNINSTALL;
1247 boolean testHidden = removalType == PackageRemovalType.HIDE;
Gustav Sennton0df2c552016-06-14 15:32:19 +01001248 String installedPackage = "installedPackage";
1249 String uninstalledPackage = "uninstalledPackage";
1250 WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
1251 new WebViewProviderInfo(uninstalledPackage, "", true /* available by default */,
1252 false /* fallback */, null),
1253 new WebViewProviderInfo(installedPackage, "", true /* available by default */,
1254 false /* fallback */, null)};
1255
1256 setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
Gustav Sennton364e1602016-12-14 09:10:50 +00001257 int secondaryUserId = 5;
1258 if (multiUser) {
1259 mTestSystemImpl.addUser(secondaryUserId);
1260 // Install all packages for the primary user.
1261 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, webviewPackages);
1262 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(
1263 installedPackage, true /* enabled */, true /* valid */, true /* installed */));
1264 // Hide or uninstall the primary package for the second user
1265 mTestSystemImpl.setPackageInfo(createPackageInfo(uninstalledPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +01001266 true /* valid */, (testUninstalled ? false : true) /* installed */,
1267 null /* signatures */, 0 /* updateTime */, (testHidden ? true : false)));
Gustav Sennton364e1602016-12-14 09:10:50 +00001268 } else {
1269 mTestSystemImpl.setPackageInfo(createPackageInfo(installedPackage, true /* enabled */,
1270 true /* valid */, true /* installed */));
1271 // Hide or uninstall the primary package
1272 mTestSystemImpl.setPackageInfo(createPackageInfo(uninstalledPackage, true /* enabled */,
1273 true /* valid */, (testUninstalled ? false : true) /* installed */,
1274 null /* signatures */, 0 /* updateTime */, (testHidden ? true : false)));
1275 }
Gustav Sennton0df2c552016-06-14 15:32:19 +01001276
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001277 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001278
1279 checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
1280 }
1281
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001282 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001283 public void testCantSwitchToHiddenPackage () {
1284 checkCantSwitchToNonVisiblePackage(false /* true == uninstalled, false == hidden */);
1285 }
1286
1287
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001288 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001289 public void testCantSwitchToUninstalledPackage () {
1290 checkCantSwitchToNonVisiblePackage(true /* true == uninstalled, false == hidden */);
1291 }
1292
1293 /**
Gustav Sennton364e1602016-12-14 09:10:50 +00001294 * Ensure that we won't prioritize an uninstalled (or hidden) package even if it is user-chosen.
Gustav Sennton0df2c552016-06-14 15:32:19 +01001295 */
1296 private void checkCantSwitchToNonVisiblePackage(boolean uninstalledNotHidden) {
1297 boolean testUninstalled = uninstalledNotHidden;
1298 boolean testHidden = !uninstalledNotHidden;
1299 String installedPackage = "installedPackage";
1300 String uninstalledPackage = "uninstalledPackage";
1301 WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
1302 new WebViewProviderInfo(uninstalledPackage, "", true /* available by default */,
1303 false /* fallback */, null),
1304 new WebViewProviderInfo(installedPackage, "", true /* available by default */,
1305 false /* fallback */, null)};
1306
1307 setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
Gustav Sennton364e1602016-12-14 09:10:50 +00001308 int secondaryUserId = 412;
1309 mTestSystemImpl.addUser(secondaryUserId);
1310
1311 // Let all packages be installed and enabled for the primary user.
1312 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, webviewPackages);
1313 // Only uninstall the 'uninstalled package' for the secondary user.
1314 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(installedPackage,
1315 true /* enabled */, true /* valid */, true /* installed */));
1316 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(uninstalledPackage,
1317 true /* enabled */, true /* valid */, !testUninstalled /* installed */,
1318 null /* signatures */, 0 /* updateTime */, testHidden /* hidden */));
Gustav Sennton0df2c552016-06-14 15:32:19 +01001319
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001320 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001321
1322 checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
1323
Gustav Sennton0df2c552016-06-14 15:32:19 +01001324 // ensure that we don't switch to the uninstalled package (it will be used if it becomes
1325 // installed later)
1326 assertEquals(installedPackage,
1327 mWebViewUpdateServiceImpl.changeProviderAndSetting(uninstalledPackage));
1328
Gustav Sennton364e1602016-12-14 09:10:50 +00001329 // Ensure both packages are considered valid.
1330 assertEquals(2, mWebViewUpdateServiceImpl.getValidWebViewPackages().length);
1331
1332
Gustav Sennton0df2c552016-06-14 15:32:19 +01001333 // We should only have called onWebViewProviderChanged once (before calling
1334 // changeProviderAndSetting
1335 Mockito.verify(mTestSystemImpl, Mockito.times(1)).onWebViewProviderChanged(
1336 Mockito.argThat(new IsPackageInfoWithName(installedPackage)));
1337 }
1338
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001339 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001340 public void testHiddenPackageNotPrioritizedEvenIfChosen() {
1341 checkNonvisiblePackageNotPrioritizedEvenIfChosen(
1342 false /* true == uninstalled, false == hidden */);
1343 }
1344
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001345 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001346 public void testUninstalledPackageNotPrioritizedEvenIfChosen() {
1347 checkNonvisiblePackageNotPrioritizedEvenIfChosen(
1348 true /* true == uninstalled, false == hidden */);
1349 }
1350
1351 public void checkNonvisiblePackageNotPrioritizedEvenIfChosen(boolean uninstalledNotHidden) {
1352 boolean testUninstalled = uninstalledNotHidden;
1353 boolean testHidden = !uninstalledNotHidden;
1354 String installedPackage = "installedPackage";
1355 String uninstalledPackage = "uninstalledPackage";
1356 WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
1357 new WebViewProviderInfo(uninstalledPackage, "", true /* available by default */,
1358 false /* fallback */, null),
1359 new WebViewProviderInfo(installedPackage, "", true /* available by default */,
1360 false /* fallback */, null)};
1361
1362 setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
Gustav Sennton364e1602016-12-14 09:10:50 +00001363 int secondaryUserId = 4;
1364 mTestSystemImpl.addUser(secondaryUserId);
1365
1366 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, webviewPackages);
1367 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(installedPackage,
1368 true /* enabled */, true /* valid */, true /* installed */));
1369 mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(uninstalledPackage,
1370 true /* enabled */, true /* valid */,
1371 (testUninstalled ? false : true) /* installed */, null /* signatures */,
1372 0 /* updateTime */, (testHidden ? true : false) /* hidden */));
Gustav Sennton0df2c552016-06-14 15:32:19 +01001373
1374 // Start with the setting pointing to the uninstalled package
1375 mTestSystemImpl.updateUserSetting(null, uninstalledPackage);
1376
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001377 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001378
1379 checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
1380 }
1381
Gustav Sennton364e1602016-12-14 09:10:50 +00001382 @Test
1383 public void testFallbackEnabledIfPrimaryUninstalledSingleUser() {
1384 checkFallbackEnabledIfPrimaryUninstalled(false /* multiUser */);
1385 }
1386
1387 @Test
1388 public void testFallbackEnabledIfPrimaryUninstalledMultiUser() {
1389 checkFallbackEnabledIfPrimaryUninstalled(true /* multiUser */);
1390 }
1391
Gustav Sennton0df2c552016-06-14 15:32:19 +01001392 /**
Gustav Sennton364e1602016-12-14 09:10:50 +00001393 * Ensures that fallback becomes enabled at boot if the primary package is uninstalled for some
Gustav Sennton0df2c552016-06-14 15:32:19 +01001394 * user.
1395 */
Gustav Sennton364e1602016-12-14 09:10:50 +00001396 private void checkFallbackEnabledIfPrimaryUninstalled(boolean multiUser) {
Gustav Sennton0df2c552016-06-14 15:32:19 +01001397 String primaryPackage = "primary";
1398 String fallbackPackage = "fallback";
1399 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1400 new WebViewProviderInfo(
1401 primaryPackage, "", true /* default available */, false /* fallback */, null),
1402 new WebViewProviderInfo(
1403 fallbackPackage, "", true /* default available */, true /* fallback */, null)};
1404 setupWithPackages(packages, true /* fallback logic enabled */);
Gustav Sennton364e1602016-12-14 09:10:50 +00001405 int secondaryUserId = 5;
1406 if (multiUser) {
1407 mTestSystemImpl.addUser(secondaryUserId);
1408 // Install all packages for the primary user.
1409 setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
1410 // Only install fallback package for secondary user.
1411 mTestSystemImpl.setPackageInfoForUser(secondaryUserId,
1412 createPackageInfo(primaryPackage, true /* enabled */,
1413 true /* valid */, false /* installed */));
1414 mTestSystemImpl.setPackageInfoForUser(secondaryUserId,
1415 createPackageInfo(fallbackPackage, false /* enabled */,
1416 true /* valid */, true /* installed */));
1417 } else {
1418 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +01001419 true /* valid */, false /* installed */));
Gustav Sennton364e1602016-12-14 09:10:50 +00001420 mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, false /* enabled */,
Gustav Sennton0df2c552016-06-14 15:32:19 +01001421 true /* valid */, true /* installed */));
Gustav Sennton364e1602016-12-14 09:10:50 +00001422 }
Gustav Sennton0df2c552016-06-14 15:32:19 +01001423
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001424 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001425 // Verify that we enable the fallback package
1426 Mockito.verify(mTestSystemImpl).enablePackageForAllUsers(
1427 Mockito.anyObject(), Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */);
1428
1429 checkPreparationPhasesForPackage(fallbackPackage, 1 /* first preparation phase */);
1430 }
1431
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001432 @Test
Gustav Sennton0df2c552016-06-14 15:32:19 +01001433 public void testPreparationRunsIffNewPackage() {
1434 String primaryPackage = "primary";
1435 String fallbackPackage = "fallback";
1436 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1437 new WebViewProviderInfo(
1438 primaryPackage, "", true /* default available */, false /* fallback */, null),
1439 new WebViewProviderInfo(
1440 fallbackPackage, "", true /* default available */, true /* fallback */, null)};
1441 setupWithPackages(packages, true /* fallback logic enabled */);
1442 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1443 true /* valid */, true /* installed */, null /* signatures */,
1444 10 /* lastUpdateTime*/ ));
1445 mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
1446 true /* valid */, true /* installed */));
1447
Gustav Sennton86f7bbe2016-10-24 16:49:32 +01001448 runWebViewBootPreparationOnMainSync();
Gustav Sennton0df2c552016-06-14 15:32:19 +01001449
1450 checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
1451 Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
1452 Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
1453 Matchers.anyInt() /* user */);
1454
1455
1456 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1457 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0 /* userId */);
1458 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1459 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 1 /* userId */);
1460 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1461 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 2 /* userId */);
1462 // package still has the same update-time so we shouldn't run preparation here
1463 Mockito.verify(mTestSystemImpl, Mockito.times(1)).onWebViewProviderChanged(
1464 Mockito.argThat(new IsPackageInfoWithName(primaryPackage)));
1465 Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
1466 Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
1467 Matchers.anyInt() /* user */);
1468
1469 // Ensure we can still load the package
1470 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
1471 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, response.status);
1472 assertEquals(primaryPackage, response.packageInfo.packageName);
1473
1474
1475 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1476 true /* valid */, true /* installed */, null /* signatures */,
1477 20 /* lastUpdateTime*/ ));
1478 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1479 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
1480 // The package has now changed - ensure that we have run the preparation phase a second time
1481 checkPreparationPhasesForPackage(primaryPackage, 2 /* second preparation phase */);
1482
1483
1484 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1485 true /* valid */, true /* installed */, null /* signatures */,
1486 50 /* lastUpdateTime*/ ));
1487 // Receive intent for different user
1488 mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
1489 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 2);
1490
1491 checkPreparationPhasesForPackage(primaryPackage, 3 /* third preparation phase */);
1492 }
Gustav Senntonbf683e02016-09-15 14:42:50 +01001493
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001494 @Test
Gustav Senntonbf683e02016-09-15 14:42:50 +01001495 public void testGetCurrentWebViewPackage() {
1496 PackageInfo firstPackage = createPackageInfo("first", true /* enabled */,
1497 true /* valid */, true /* installed */);
1498 firstPackage.versionCode = 100;
1499 firstPackage.versionName = "first package version";
1500 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1501 new WebViewProviderInfo(firstPackage.packageName, "", true, false, null)};
1502 setupWithPackages(packages, true);
1503 mTestSystemImpl.setPackageInfo(firstPackage);
1504
Torne (Richard Coles)ab5d0ba2016-11-03 15:09:34 +00001505 runWebViewBootPreparationOnMainSync();
Gustav Senntonbf683e02016-09-15 14:42:50 +01001506
1507 Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
1508 Mockito.argThat(new IsPackageInfoWithName(firstPackage.packageName)));
1509
1510 mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
1511
1512 // Ensure the API is correct before running waitForAndGetProvider
1513 assertEquals(firstPackage.packageName,
1514 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
Dianne Hackborn3accca02013-09-20 09:32:11 -07001515 assertEquals(firstPackage.getLongVersionCode(),
1516 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().getLongVersionCode());
Gustav Senntonbf683e02016-09-15 14:42:50 +01001517 assertEquals(firstPackage.versionName,
1518 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionName);
1519
1520 WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
1521 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, response.status);
1522 assertEquals(firstPackage.packageName, response.packageInfo.packageName);
1523
1524 // Ensure the API is still correct after running waitForAndGetProvider
1525 assertEquals(firstPackage.packageName,
1526 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
Dianne Hackborn3accca02013-09-20 09:32:11 -07001527 assertEquals(firstPackage.getLongVersionCode(),
1528 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().getLongVersionCode());
Gustav Senntonbf683e02016-09-15 14:42:50 +01001529 assertEquals(firstPackage.versionName,
1530 mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionName);
1531 }
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001532
1533 @Test
1534 public void testMultiProcessEnabledByDefault() {
Gustav Senntonb2650162017-04-07 14:41:38 +01001535 testMultiProcessByDefault(true /* enabledByDefault */);
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001536 }
1537
1538 @Test
1539 public void testMultiProcessDisabledByDefault() {
Gustav Senntonb2650162017-04-07 14:41:38 +01001540 testMultiProcessByDefault(false /* enabledByDefault */);
1541 }
1542
1543 private void testMultiProcessByDefault(boolean enabledByDefault) {
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001544 String primaryPackage = "primary";
1545 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1546 new WebViewProviderInfo(
1547 primaryPackage, "", true /* default available */, false /* fallback */, null)};
1548 setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
Gustav Senntonb2650162017-04-07 14:41:38 +01001549 true /* debuggable */,
1550 enabledByDefault /* not multiprocess by default */);
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001551 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1552 true /* valid */, true /* installed */, null /* signatures */,
1553 10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
1554 false /* isSystemApp */));
1555
1556 runWebViewBootPreparationOnMainSync();
1557 checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
1558
1559 // Check it's off by default
Gustav Senntonb2650162017-04-07 14:41:38 +01001560 assertEquals(enabledByDefault, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001561
1562 // Test toggling it
Gustav Senntonb2650162017-04-07 14:41:38 +01001563 mWebViewUpdateServiceImpl.enableMultiProcess(!enabledByDefault);
1564 assertEquals(!enabledByDefault, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
1565 mWebViewUpdateServiceImpl.enableMultiProcess(enabledByDefault);
1566 assertEquals(enabledByDefault, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
Torne (Richard Coles)dc375072017-01-11 15:48:13 +00001567 }
Gustav Sennton564c2fd2017-01-30 18:08:01 +00001568
Gustav Senntonb2650162017-04-07 14:41:38 +01001569 @Test
1570 public void testMultiProcessEnabledByDefaultWithSettingsValue() {
1571 testMultiProcessByDefaultWithSettingsValue(
1572 true /* enabledByDefault */, Integer.MIN_VALUE, false /* expectEnabled */);
1573 testMultiProcessByDefaultWithSettingsValue(
1574 true /* enabledByDefault */, -999999, true /* expectEnabled */);
1575 testMultiProcessByDefaultWithSettingsValue(
1576 true /* enabledByDefault */, 0, true /* expectEnabled */);
1577 testMultiProcessByDefaultWithSettingsValue(
1578 true /* enabledByDefault */, 999999, true /* expectEnabled */);
1579 }
1580
1581 @Test
1582 public void testMultiProcessDisabledByDefaultWithSettingsValue() {
1583 testMultiProcessByDefaultWithSettingsValue(
1584 false /* enabledByDefault */, Integer.MIN_VALUE, false /* expectEnabled */);
1585 testMultiProcessByDefaultWithSettingsValue(
1586 false /* enabledByDefault */, 0, false /* expectEnabled */);
1587 testMultiProcessByDefaultWithSettingsValue(
1588 false /* enabledByDefault */, 999999, false /* expectEnabled */);
1589 testMultiProcessByDefaultWithSettingsValue(
1590 false /* enabledByDefault */, Integer.MAX_VALUE, true /* expectEnabled */);
1591 }
1592
1593 /**
1594 * Test the logic of the multiprocess setting depending on whether multiprocess is enabled by
1595 * default, and what the setting is set to.
1596 * @param enabledByDefault whether multiprocess is enabled by default.
1597 * @param settingValue value of the multiprocess setting.
1598 */
1599 private void testMultiProcessByDefaultWithSettingsValue(
1600 boolean enabledByDefault, int settingValue, boolean expectEnabled) {
1601 String primaryPackage = "primary";
1602 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1603 new WebViewProviderInfo(
1604 primaryPackage, "", true /* default available */, false /* fallback */, null)};
1605 setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
1606 true /* debuggable */, enabledByDefault /* multiprocess by default */);
1607 mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
1608 true /* valid */, true /* installed */, null /* signatures */,
1609 10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
1610 false /* isSystemApp */));
1611
1612 runWebViewBootPreparationOnMainSync();
1613 checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
1614
1615 mTestSystemImpl.setMultiProcessSetting(null /* context */, settingValue);
1616
1617 assertEquals(expectEnabled, mWebViewUpdateServiceImpl.isMultiProcessEnabled());
1618 }
1619
1620
Gustav Sennton564c2fd2017-01-30 18:08:01 +00001621 /**
1622 * Ensure that packages with a targetSdkVersion targeting the current platform are valid, and
1623 * that packages targeting an older version are not valid.
1624 */
1625 @Test
1626 public void testTargetSdkVersionValidity() {
1627 PackageInfo newSdkPackage = createPackageInfo("newTargetSdkPackage",
1628 true /* enabled */, true /* valid */, true /* installed */);
1629 newSdkPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
1630 PackageInfo currentSdkPackage = createPackageInfo("currentTargetSdkPackage",
1631 true /* enabled */, true /* valid */, true /* installed */);
Gustav Senntone5468f72017-11-20 19:42:43 +00001632 currentSdkPackage.applicationInfo.targetSdkVersion = UserPackage.MINIMUM_SUPPORTED_SDK;
Gustav Sennton564c2fd2017-01-30 18:08:01 +00001633 PackageInfo oldSdkPackage = createPackageInfo("oldTargetSdkPackage",
1634 true /* enabled */, true /* valid */, true /* installed */);
Gustav Senntone5468f72017-11-20 19:42:43 +00001635 oldSdkPackage.applicationInfo.targetSdkVersion = UserPackage.MINIMUM_SUPPORTED_SDK - 1;
Gustav Sennton564c2fd2017-01-30 18:08:01 +00001636
1637 WebViewProviderInfo newSdkProviderInfo =
1638 new WebViewProviderInfo(newSdkPackage.packageName, "", true, false, null);
1639 WebViewProviderInfo currentSdkProviderInfo =
1640 new WebViewProviderInfo(currentSdkPackage.packageName, "", true, false, null);
1641 WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
1642 new WebViewProviderInfo(oldSdkPackage.packageName, "", true, false, null),
1643 currentSdkProviderInfo, newSdkProviderInfo};
1644 setupWithPackages(packages, true);
1645;
1646 mTestSystemImpl.setPackageInfo(newSdkPackage);
1647 mTestSystemImpl.setPackageInfo(currentSdkPackage);
1648 mTestSystemImpl.setPackageInfo(oldSdkPackage);
1649
1650 assertArrayEquals(new WebViewProviderInfo[]{currentSdkProviderInfo, newSdkProviderInfo},
1651 mWebViewUpdateServiceImpl.getValidWebViewPackages());
1652
1653 runWebViewBootPreparationOnMainSync();
1654
1655 checkPreparationPhasesForPackage(currentSdkPackage.packageName,
1656 1 /* first preparation phase */);
1657 }
Gustav Sennton53b78242016-04-07 15:56:10 +01001658}