1 /*
2  * Copyright (C) 2014 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 
17 package android.appsecurity.cts;
18 
19 import static android.appsecurity.cts.Utils.ABI_TO_APK;
20 import static android.appsecurity.cts.Utils.APK;
21 import static android.appsecurity.cts.Utils.APK_hdpi;
22 import static android.appsecurity.cts.Utils.APK_mdpi;
23 import static android.appsecurity.cts.Utils.APK_xhdpi;
24 import static android.appsecurity.cts.Utils.APK_xxhdpi;
25 import static android.appsecurity.cts.Utils.CLASS;
26 import static android.appsecurity.cts.Utils.PKG;
27 
28 import static org.junit.Assert.assertNotNull;
29 
30 import android.content.pm.Flags;
31 import android.platform.test.annotations.AppModeFull;
32 import android.platform.test.annotations.AppModeInstant;
33 import android.platform.test.annotations.PlatinumTest;
34 import android.platform.test.annotations.Presubmit;
35 import android.platform.test.annotations.RequiresFlagsDisabled;
36 import android.platform.test.annotations.RequiresFlagsEnabled;
37 import android.platform.test.flag.junit.CheckFlagsRule;
38 import android.platform.test.flag.junit.host.HostFlagsValueProvider;
39 
40 import com.android.compatibility.common.util.CpuFeatures;
41 import com.android.tradefed.device.DeviceNotAvailableException;
42 import com.android.tradefed.testtype.Abi;
43 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
44 import com.android.tradefed.testtype.IAbi;
45 import com.android.tradefed.util.AbiUtils;
46 
47 import org.junit.After;
48 import org.junit.Assume;
49 import org.junit.Before;
50 import org.junit.Rule;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 
54 import java.io.FileNotFoundException;
55 import java.util.HashMap;
56 import java.util.Set;
57 
58 /**
59  * Tests that verify installing of various split APKs from host side.
60  */
61 @Presubmit
62 @PlatinumTest(focusArea = "pm")
63 @RunWith(DeviceJUnit4ClassRunner.class)
64 public class SplitTests extends BaseAppSecurityTest {
65     static final String PKG_NO_RESTART = "com.android.cts.norestart";
66     static final String APK_NO_RESTART_BASE = "CtsNoRestartBase.apk";
67     static final String APK_NO_RESTART_FEATURE = "CtsNoRestartFeature.apk";
68 
69     static final String APK_NEED_SPLIT_BASE = "CtsNeedSplitApp.apk";
70     static final String APK_NEED_SPLIT_FEATURE_WARM = "CtsNeedSplitFeatureWarm.apk";
71     static final String APK_NEED_SPLIT_CONFIG = "CtsNeedSplitApp_xxhdpi-v4.apk";
72 
73     static final String APK_REQUIRED_SPLIT_TYPE_BASE = "CtsRequiredSplitTypeSplitApp.apk";
74     static final String APK_REQUIRED_SPLIT_TYPE_BASE_UPDATED =
75             "CtsRequiredSplitTypeSplitAppUpdated.apk";
76     static final String APK_REQUIRED_SPLIT_TYPE_DENSITY = "CtsSplitAppTypeDensity.apk";
77     static final String APK_REQUIRED_SPLIT_TYPE_LOCALE = "CtsSplitAppTypeLocale.apk";
78     static final String APK_REQUIRED_SPLIT_TYPE_FOO = "CtsSplitAppTypeFoo.apk";
79     static final String APK_REQUIRED_SPLIT_TYPE_MULTIPLE = "CtsSplitAppTypeMultiple.apk";
80     static final String APK_REQUIRED_SPLIT_TYPE_FEATURE = "CtsSplitAppTypeFeature.apk";
81     static final String APK_REQUIRED_SPLIT_TYPE_FEATURE_DATA = "CtsSplitAppTypeFeatureData.apk";
82     static final String APK_REQUIRED_SPLIT_TYPE_FEATURE_FOO = "CtsSplitAppTypeFeatureFoo.apk";
83     static final String APK_INVALID_REQUIRED_SPLIT_TYPE_BASE =
84             "CtsInvalidRequiredSplitTypeSplitApp.apk";
85 
86     private static final String APK_v7 = "CtsSplitApp_v7.apk";
87     private static final String APK_v23 = "CtsSplitApp_v23.apk";
88     private static final String APK_fr = "CtsSplitApp_fr.apk";
89     private static final String APK_de = "CtsSplitApp_de.apk";
90 
91     private static final String APK_NUMBER_PROVIDER_A = "CtsSplitApp_number_provider_a.apk";
92     private static final String APK_NUMBER_PROVIDER_B = "CtsSplitApp_number_provider_b.apk";
93     private static final String APK_NUMBER_PROXY = "CtsSplitApp_number_proxy.apk";
94 
95     private static final String APK_DIFF_REVISION = "CtsSplitAppDiffRevision.apk";
96     private static final String APK_DIFF_REVISION_v7 = "CtsSplitAppDiffRevision_v7.apk";
97 
98     private static final String APK_DIFF_VERSION = "CtsSplitAppDiffVersion.apk";
99     private static final String APK_DIFF_VERSION_v7 = "CtsSplitAppDiffVersion_v7.apk";
100 
101     private static final String APK_DIFF_CERT = "CtsSplitAppDiffCert.apk";
102     private static final String APK_DIFF_CERT_v7 = "CtsSplitAppDiffCert_v7.apk";
103 
104     private static final String APK_FEATURE_WARM = "CtsSplitAppFeatureWarm.apk";
105     private static final String APK_FEATURE_WARM_v7 = "CtsSplitAppFeatureWarm_v7.apk";
106     private static final String APK_FEATURE_WARM_v23 = "CtsSplitAppFeatureWarm_v23.apk";
107 
108     private static final String APK_FEATURE_ROSE = "CtsSplitAppFeatureRose.apk";
109     private static final String APK_FEATURE_ROSE_v23 = "CtsSplitAppFeatureRose_v23.apk";
110 
111     private static final String APK_REVISION_A = "CtsSplitAppRevisionA.apk";
112     private static final String APK_FEATURE_WARM_REVISION_A = "CtsSplitAppFeatureWarmRevisionA.apk";
113     private static final String BITNESS_32 = "32";
114     private static final String BITNESS_64 = "64";
115 
116     // Apk includes a provider and service declared in other split apk. And only could be tested in
117     // instant app mode.
118     static final String APK_INSTANT = "CtsSplitInstantApp.apk";
119 
120     static final HashMap<String, String> ABI_TO_REVISION_APK = new HashMap<>();
121 
122     static {
123         ABI_TO_REVISION_APK.put("x86", "CtsSplitApp_revision12_x86.apk");
124         ABI_TO_REVISION_APK.put("x86_64", "CtsSplitApp_revision12_x86_64.apk");
125         ABI_TO_REVISION_APK.put("armeabi-v7a", "CtsSplitApp_revision12_armeabi-v7a.apk");
126         ABI_TO_REVISION_APK.put("armeabi", "CtsSplitApp_revision12_armeabi.apk");
127         ABI_TO_REVISION_APK.put("arm64-v8a", "CtsSplitApp_revision12_arm64-v8a.apk");
128         ABI_TO_REVISION_APK.put("mips64", "CtsSplitApp_revision12_mips64.apk");
129         ABI_TO_REVISION_APK.put("mips", "CtsSplitApp_revision12_mips.apk");
130     }
131 
132     @Rule
133     public final CheckFlagsRule mCheckFlagsRule =
134             HostFlagsValueProvider.createCheckFlagsRule(this::getDevice);
135 
136     private String mDeviceDefaultAbi = null;
137     private String mDeviceDefaultBitness = null;
138     private String mDeviceDefaultBaseArch = null;
139     private String[] mDeviceSupported32BitSet = null;
140     private String[] mDeviceSupported64BitSet = null;
141 
getDeviceSupported32AbiSet()142     private String[] getDeviceSupported32AbiSet() throws Exception {
143         if (mDeviceSupported32BitSet != null) {
144             return mDeviceSupported32BitSet;
145         }
146         mDeviceSupported32BitSet = getDeviceSupportedAbiSet(BITNESS_32);
147         return mDeviceSupported32BitSet;
148     }
149 
getDeviceSupported64AbiSet()150     private String[] getDeviceSupported64AbiSet() throws Exception {
151         if (mDeviceSupported64BitSet != null) {
152             return mDeviceSupported64BitSet;
153         }
154         mDeviceSupported64BitSet = getDeviceSupportedAbiSet(BITNESS_64);
155         return mDeviceSupported64BitSet;
156     }
157 
getDeviceSupportedAbiSet(String bitness)158     private String[] getDeviceSupportedAbiSet(String bitness) throws Exception {
159         String abis = getDevice().getProperty("ro.product.cpu.abilist" + bitness);
160         if (abis == null) {
161             return new String[0];
162         }
163         return abis.split(",");
164     }
165 
getDeviceDefaultAbi()166     private String getDeviceDefaultAbi() throws Exception {
167         if (mDeviceDefaultAbi != null) {
168             return mDeviceDefaultAbi;
169         }
170         mDeviceDefaultAbi = getDevice().getProperty("ro.product.cpu.abi");
171         return mDeviceDefaultAbi;
172     }
173 
getDeviceDefaultBitness()174     private String getDeviceDefaultBitness() throws Exception {
175         if (mDeviceDefaultBitness != null) {
176             return mDeviceDefaultBitness;
177         }
178         mDeviceDefaultBitness = AbiUtils.getBitness(getDeviceDefaultAbi());
179         return mDeviceDefaultBitness;
180     }
181 
getDeviceDefaultBaseArch()182     private String getDeviceDefaultBaseArch() throws Exception {
183         if (mDeviceDefaultBaseArch != null) {
184             return mDeviceDefaultBaseArch;
185         }
186         mDeviceDefaultBaseArch = AbiUtils.getBaseArchForAbi(getDeviceDefaultAbi());
187         return mDeviceDefaultBaseArch;
188     }
189 
190     /*
191      * Return true if the device supports both 32 bit and 64 bit ABIs. Otherwise, false.
192      */
isDeviceSupportedBothBitness()193     private boolean isDeviceSupportedBothBitness() throws Exception {
194         final String deviceDefaultBaseArch = getDeviceDefaultBaseArch();
195         if (getDeviceDefaultBitness().equals(BITNESS_32)) {
196             String[] abis64 = getDeviceSupported64AbiSet();
197             for (int i = 0; i < abis64.length; i++) {
198                 if (AbiUtils.getBaseArchForAbi(abis64[i]).equals(deviceDefaultBaseArch)) {
199                     return true;
200                 }
201             }
202         } else {
203             String[] abis32 = getDeviceSupported32AbiSet();
204             for (int i = 0; i < abis32.length; i++) {
205                 if (AbiUtils.getBaseArchForAbi(abis32[i]).equals(deviceDefaultBaseArch)) {
206                     return true;
207                 }
208             }
209         }
210 
211         return false;
212     }
213 
214     @Before
setUp()215     public void setUp() throws Exception {
216         Utils.prepareSingleUser(getDevice());
217         getDevice().uninstallPackage(PKG);
218         getDevice().uninstallPackage(PKG_NO_RESTART);
219     }
220 
221     @After
tearDown()222     public void tearDown() throws Exception {
223         getDevice().uninstallPackage(PKG);
224         getDevice().uninstallPackage(PKG_NO_RESTART);
225     }
226 
227     @Test
228     @AppModeFull(reason = "'full' portion of the hostside test")
testSingleBase_full()229     public void testSingleBase_full() throws Exception {
230         testSingleBase(false);
231     }
232     @Test
233     @AppModeInstant(reason = "'instant' portion of the hostside test")
testSingleBase_instant()234     public void testSingleBase_instant() throws Exception {
235         testSingleBase(true);
236     }
testSingleBase(boolean instant)237     private void testSingleBase(boolean instant) throws Exception {
238         new InstallMultiple(instant).addFile(APK).run();
239         runDeviceTests(PKG, CLASS, "testSingleBase");
240     }
241 
242     @Test
243     @AppModeFull(reason = "'full' portion of the hostside test")
testDensitySingle_full()244     public void testDensitySingle_full() throws Exception {
245         testDensitySingle(false);
246     }
247     @Test
248     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDensitySingle_instant()249     public void testDensitySingle_instant() throws Exception {
250         testDensitySingle(true);
251     }
testDensitySingle(boolean instant)252     private void testDensitySingle(boolean instant) throws Exception {
253         new InstallMultiple(instant).addFile(APK).addFile(APK_mdpi).run();
254         runDeviceTests(PKG, CLASS, "testDensitySingle");
255     }
256 
257     @Test
258     @AppModeFull(reason = "'full' portion of the hostside test")
testDensityAll_full()259     public void testDensityAll_full() throws Exception {
260         testDensityAll(false);
261     }
262     @Test
263     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDensityAll_instant()264     public void testDensityAll_instant() throws Exception {
265         testDensityAll(true);
266     }
testDensityAll(boolean instant)267     private void testDensityAll(boolean instant) throws Exception {
268         new InstallMultiple(instant).addFile(APK).addFile(APK_mdpi).addFile(APK_hdpi).addFile(APK_xhdpi)
269                 .addFile(APK_xxhdpi).run();
270         runDeviceTests(PKG, CLASS, "testDensityAll");
271     }
272 
273     /**
274      * Install first with low-resolution resources, then add a split that offers
275      * higher-resolution resources.
276      */
277     @Test
278     @AppModeFull(reason = "'full' portion of the hostside test")
testDensityBest_full()279     public void testDensityBest_full() throws Exception {
280         testDensityBest(false);
281     }
282     @Test
283     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDensityBest_instant()284     public void testDensityBest_instant() throws Exception {
285         testDensityBest(true);
286     }
testDensityBest(boolean instant)287     private void testDensityBest(boolean instant) throws Exception {
288         new InstallMultiple(instant).addFile(APK).addFile(APK_mdpi).run();
289         runDeviceTests(PKG, CLASS, "testDensityBest1");
290 
291         // Now splice in an additional split which offers better resources
292         new InstallMultiple(instant).inheritFrom(PKG).addFile(APK_xxhdpi).run();
293         runDeviceTests(PKG, CLASS, "testDensityBest2");
294     }
295 
296     /**
297      * Verify that an API-based split can change enabled/disabled state of
298      * manifest elements.
299      */
300     @Test
301     @AppModeFull(reason = "'full' portion of the hostside test")
testApi_full()302     public void testApi_full() throws Exception {
303         testApi(false);
304     }
305     @Test
306     @AppModeInstant(reason = "'instant' portion of the hostside test")
testApi_instant()307     public void testApi_instant() throws Exception {
308         testApi(true);
309     }
testApi(boolean instant)310     private void testApi(boolean instant) throws Exception {
311         new InstallMultiple(instant).addFile(APK).addFile(APK_v7).run();
312         runDeviceTests(PKG, CLASS, "testApi");
313     }
314 
315     @Test
316     @AppModeFull(reason = "'full' portion of the hostside test")
testLocale_full()317     public void testLocale_full() throws Exception {
318         testLocale(false);
319     }
320     @Test
321     @AppModeInstant(reason = "'instant' portion of the hostside test")
testLocale_instant()322     public void testLocale_instant() throws Exception {
323         testLocale(true);
324     }
testLocale(boolean instant)325     private void testLocale(boolean instant) throws Exception {
326         new InstallMultiple(instant).addFile(APK).addFile(APK_de).addFile(APK_fr).run();
327         runDeviceTests(PKG, CLASS, "testLocale");
328     }
329 
330     /**
331      * Install test app with <em>single</em> split that exactly matches the
332      * currently active ABI. This also explicitly forces ABI when installing.
333      */
334     @Test
335     @AppModeFull(reason = "'full' portion of the hostside test")
testNativeSingle_full()336     public void testNativeSingle_full() throws Exception {
337         testNativeSingle(false, false);
338     }
339     @Test
340     @AppModeInstant(reason = "'instant' portion of the hostside test")
testNativeSingle_instant()341     public void testNativeSingle_instant() throws Exception {
342         testNativeSingle(true, false);
343     }
344 
getInstallMultiple(boolean instant, boolean useNaturalAbi)345     private InstallMultiple getInstallMultiple(boolean instant, boolean useNaturalAbi) {
346         final InstallMultiple installMultiple = new InstallMultiple(instant);
347         if (useNaturalAbi) {
348             return installMultiple.useNaturalAbi();
349         }
350         return installMultiple;
351     }
352 
testNativeSingle_assertFail(boolean instant, boolean useNaturalAbi, String failure)353     private void testNativeSingle_assertFail(boolean instant, boolean useNaturalAbi,
354             String failure) throws Exception {
355         Assume.assumeTrue(isDeviceSupportedBothBitness());
356         final String abi = getAbi().getName();
357         final String apk = ABI_TO_APK.get(abi);
358         assertNotNull("Failed to find APK for ABI " + abi, apk);
359 
360         getInstallMultiple(instant, useNaturalAbi)
361                 .addFile(APK)
362                 .addFile(apk)
363                 .run(/* expectingSuccess= */ false, failure);
364     }
365 
testNativeSingle(boolean instant, boolean useNaturalAbi)366     private void testNativeSingle(boolean instant, boolean useNaturalAbi) throws Exception {
367         final String abi = getAbi().getName();
368         final String apk = ABI_TO_APK.get(abi);
369         final String revisionApk = ABI_TO_REVISION_APK.get(abi);
370         assertNotNull("Failed to find APK for ABI " + abi, apk);
371 
372         getInstallMultiple(instant, useNaturalAbi).addFile(APK).addFile(apk).run();
373         runDeviceTests(PKG, CLASS, "testNative");
374         runDeviceTests(PKG, CLASS, "testNativeRevision_sub_shouldImplementBadly");
375         getInstallMultiple(instant, useNaturalAbi).inheritFrom(PKG).addFile(revisionApk).run();
376         runDeviceTests(PKG, CLASS, "testNativeRevision_sub_shouldImplementWell");
377 
378         getInstallMultiple(instant, useNaturalAbi).inheritFrom(PKG)
379                 .addFile(APK_NUMBER_PROVIDER_A)
380                 .addFile(APK_NUMBER_PROVIDER_B)
381                 .addFile(APK_NUMBER_PROXY).run();
382         runDeviceTests(PKG, CLASS, "testNative_getNumberADirectly_shouldBeSeven");
383         runDeviceTests(PKG, CLASS, "testNative_getNumberAViaProxy_shouldBeSeven");
384         runDeviceTests(PKG, CLASS, "testNative_getNumberBDirectly_shouldBeEleven");
385         runDeviceTests(PKG, CLASS, "testNative_getNumberBViaProxy_shouldBeEleven");
386     }
387 
388     @Test
389     @AppModeFull(reason = "'full' portion of the hostside test")
testNativeSplitForEachSupportedAbi_full()390     public void testNativeSplitForEachSupportedAbi_full() throws Exception {
391         testNativeForEachSupportedAbi(false);
392     }
393 
394     @Test
395     @AppModeInstant(reason = "'instant' portion of the hostside test")
testNativeSplitForEachSupportedAbi_instant()396     public void testNativeSplitForEachSupportedAbi_instant() throws Exception {
397         testNativeForEachSupportedAbi(true);
398     }
399 
400 
specifyAbiToTest(boolean instant, String abiListProperty, String testMethodName)401     private void specifyAbiToTest(boolean instant, String abiListProperty, String testMethodName)
402             throws FileNotFoundException, DeviceNotAvailableException {
403         final String propertyAbiListValue = getDevice().getProperty(abiListProperty);
404         final Set<String> supportedAbiSet =
405                 AbiUtils.parseAbiListFromProperty(propertyAbiListValue);
406         for (String abi : supportedAbiSet) {
407             String apk = ABI_TO_APK.get(abi);
408             new InstallMultiple(instant, true).inheritFrom(PKG).addFile(apk).run();
409 
410             // Without specifying abi for executing "adb shell am",
411             // a UnsatisfiedLinkError will happen.
412             IAbi iAbi = new Abi(abi, AbiUtils.getBitness(abi));
413             setAbi(iAbi);
414             runDeviceTests(PKG, CLASS, testMethodName);
415         }
416     }
417 
testNativeForEachSupportedAbi(boolean instant)418     private void testNativeForEachSupportedAbi(boolean instant)
419             throws DeviceNotAvailableException, FileNotFoundException {
420         new InstallMultiple(instant, true).addFile(APK).run();
421 
422         // make sure this device can run both 32 bit and 64 bit
423         specifyAbiToTest(instant, "ro.product.cpu.abilist64", "testNative64Bit");
424         specifyAbiToTest(instant, "ro.product.cpu.abilist32", "testNative32Bit");
425     }
426 
427     /**
428      * Install test app with <em>single</em> split that exactly matches the
429      * currently active ABI. This variant <em>does not</em> force the ABI when
430      * installing, instead exercising the system's ability to choose the ABI
431      * through inspection of the installed app.
432      */
433     @Test
434     @AppModeFull(reason = "'full' portion of the hostside test")
435     @RequiresFlagsDisabled(Flags.FLAG_FORCE_MULTI_ARCH_NATIVE_LIBS_MATCH)
testNativeSingleNatural_full()436     public void testNativeSingleNatural_full() throws Exception {
437         testNativeSingle(false, true);
438     }
439     @Test
440     @AppModeInstant(reason = "'instant' portion of the hostside test")
441     @RequiresFlagsDisabled(Flags.FLAG_FORCE_MULTI_ARCH_NATIVE_LIBS_MATCH)
testNativeSingleNatural_instant()442     public void testNativeSingleNatural_instant() throws Exception {
443         testNativeSingle(true, true);
444     }
445 
446     @Test
447     @AppModeFull(reason = "'full' portion of the hostside test")
448     @RequiresFlagsEnabled(Flags.FLAG_FORCE_MULTI_ARCH_NATIVE_LIBS_MATCH)
testNativeSingleNatural_full_fail()449     public void testNativeSingleNatural_full_fail() throws Exception {
450         testNativeSingle_assertFail(/* instant= */ false, /* useNaturalAbi= */ true,
451                 "don't support all the natively supported ABIs of the device");
452     }
453     @Test
454     @AppModeInstant(reason = "'instant' portion of the hostside test")
455     @RequiresFlagsEnabled(Flags.FLAG_FORCE_MULTI_ARCH_NATIVE_LIBS_MATCH)
testNativeSingleNatural_instant_fail()456     public void testNativeSingleNatural_instant_fail() throws Exception {
457         testNativeSingle_assertFail(/* instant= */ true, /* useNaturalAbi= */ true,
458                 "don't support all the natively supported ABIs of the device");
459     }
460 
assumeNativeAbi()461     private void assumeNativeAbi() throws Exception {
462         // Skip this test if not running on the device's native abi.
463         Assume.assumeTrue(CpuFeatures.isNativeAbi(getDevice(), getAbi().getName()));
464     }
465     /**
466      * Install test app with <em>all</em> possible ABI splits. This also
467      * explicitly forces ABI when installing.
468      */
469     @Test
470     @AppModeFull(reason = "'full' portion of the hostside test")
testNativeAll_full()471     public void testNativeAll_full() throws Exception {
472         assumeNativeAbi();
473         testNativeAll(false, false);
474     }
475     @Test
476     @AppModeInstant(reason = "'instant' portion of the hostside test")
testNativeAll_instant()477     public void testNativeAll_instant() throws Exception {
478         testNativeAll(true, false);
479     }
testNativeAll(boolean instant, boolean useNaturalAbi)480     private void testNativeAll(boolean instant, boolean useNaturalAbi) throws Exception {
481         final InstallMultiple inst = getInstallMultiple(instant, useNaturalAbi).addFile(APK);
482         for (String apk : ABI_TO_APK.values()) {
483             inst.addFile(apk);
484         }
485         inst.run();
486         runDeviceTests(PKG, CLASS, "testNative");
487         runDeviceTests(PKG, CLASS, "testNativeRevision_sub_shouldImplementBadly");
488 
489         final InstallMultiple instInheritFrom =
490                 getInstallMultiple(instant, useNaturalAbi).inheritFrom(PKG);
491         for (String apk : ABI_TO_REVISION_APK.values()) {
492             instInheritFrom.addFile(apk);
493         }
494         instInheritFrom.addFile(APK_NUMBER_PROVIDER_A);
495         instInheritFrom.addFile(APK_NUMBER_PROVIDER_B);
496         instInheritFrom.addFile(APK_NUMBER_PROXY);
497         instInheritFrom.run();
498         runDeviceTests(PKG, CLASS, "testNativeRevision_sub_shouldImplementWell");
499 
500         runDeviceTests(PKG, CLASS, "testNative_getNumberADirectly_shouldBeSeven");
501         runDeviceTests(PKG, CLASS, "testNative_getNumberAViaProxy_shouldBeSeven");
502         runDeviceTests(PKG, CLASS, "testNative_getNumberBDirectly_shouldBeEleven");
503         runDeviceTests(PKG, CLASS, "testNative_getNumberBViaProxy_shouldBeEleven");
504     }
505 
506     /**
507      * Install test app with <em>all</em> possible ABI splits. This variant
508      * <em>does not</em> force the ABI when installing, instead exercising the
509      * system's ability to choose the ABI through inspection of the installed
510      * app.
511      */
512     @Test
513     @AppModeFull(reason = "'full' portion of the hostside test")
testNativeAllNatural_full()514     public void testNativeAllNatural_full() throws Exception {
515         assumeNativeAbi();
516         testNativeAll(false, true);
517     }
518     @Test
519     @AppModeInstant(reason = "'instant' portion of the hostside test")
testNativeAllNatural_instant()520     public void testNativeAllNatural_instant() throws Exception {
521         testNativeAll(true, true);
522     }
523 
524     @Test
525     @AppModeFull(reason = "'full' portion of the hostside test")
testDuplicateBase_full()526     public void testDuplicateBase_full() throws Exception {
527         testDuplicateBase(false);
528     }
529     @Test
530     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDuplicateBase_instant()531     public void testDuplicateBase_instant() throws Exception {
532         testDuplicateBase(true);
533     }
testDuplicateBase(boolean instant)534     private void testDuplicateBase(boolean instant) throws Exception {
535         new InstallMultiple(instant).addFile(APK).addFile(APK).runExpectingFailure();
536     }
537 
538     @Test
539     @AppModeFull(reason = "'full' portion of the hostside test")
testDuplicateSplit_full()540     public void testDuplicateSplit_full() throws Exception {
541         testDuplicateSplit(false);
542     }
543     @Test
544     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDuplicateSplit_instant()545     public void testDuplicateSplit_instant() throws Exception {
546         testDuplicateSplit(true);
547     }
testDuplicateSplit(boolean instant)548     private void testDuplicateSplit(boolean instant) throws Exception {
549         new InstallMultiple(instant).addFile(APK).addFile(APK_v7).addFile(APK_v7).runExpectingFailure();
550     }
551 
552     @Test
553     @AppModeFull(reason = "'full' portion of the hostside test")
testDiffCert_full()554     public void testDiffCert_full() throws Exception {
555         testDiffCert(false);
556     }
557     @Test
558     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDiffCert_instant()559     public void testDiffCert_instant() throws Exception {
560         testDiffCert(true);
561     }
testDiffCert(boolean instant)562     private void testDiffCert(boolean instant) throws Exception {
563         new InstallMultiple(instant).addFile(APK).addFile(APK_DIFF_CERT_v7).runExpectingFailure();
564     }
565 
566     @Test
567     @AppModeFull(reason = "'full' portion of the hostside test")
testDiffCertInherit_full()568     public void testDiffCertInherit_full() throws Exception {
569         testDiffCertInherit(false);
570     }
571     @Test
572     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDiffCertInherit_instant()573     public void testDiffCertInherit_instant() throws Exception {
574         testDiffCertInherit(true);
575     }
testDiffCertInherit(boolean instant)576     private void testDiffCertInherit(boolean instant) throws Exception {
577         new InstallMultiple(instant).addFile(APK).run();
578         new InstallMultiple(instant).inheritFrom(PKG).addFile(APK_DIFF_CERT_v7).runExpectingFailure();
579     }
580 
581     @Test
582     @AppModeFull(reason = "'full' portion of the hostside test")
testDiffVersion_full()583     public void testDiffVersion_full() throws Exception {
584         testDiffVersion(false);
585     }
586     @Test
587     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDiffVersion_instant()588     public void testDiffVersion_instant() throws Exception {
589         testDiffVersion(true);
590     }
testDiffVersion(boolean instant)591     private void testDiffVersion(boolean instant) throws Exception {
592         new InstallMultiple(instant).addFile(APK).addFile(APK_DIFF_VERSION_v7).runExpectingFailure();
593     }
594 
595     @Test
596     @AppModeFull(reason = "'full' portion of the hostside test")
testDiffVersionInherit_full()597     public void testDiffVersionInherit_full() throws Exception {
598         testDiffVersionInherit(false);
599     }
600     @Test
601     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDiffVersionInherit_instant()602     public void testDiffVersionInherit_instant() throws Exception {
603         testDiffVersionInherit(true);
604     }
testDiffVersionInherit(boolean instant)605     private void testDiffVersionInherit(boolean instant) throws Exception {
606         new InstallMultiple(instant).addFile(APK).run();
607         new InstallMultiple(instant).inheritFrom(PKG).addFile(APK_DIFF_VERSION_v7).runExpectingFailure();
608     }
609 
610     @Test
611     @AppModeFull(reason = "'full' portion of the hostside test")
testDiffRevision_full()612     public void testDiffRevision_full() throws Exception {
613         testDiffRevision(false);
614     }
615     @Test
616     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDiffRevision_instant()617     public void testDiffRevision_instant() throws Exception {
618         testDiffRevision(true);
619     }
testDiffRevision(boolean instant)620     private void testDiffRevision(boolean instant) throws Exception {
621         new InstallMultiple(instant).addFile(APK).addFile(APK_DIFF_REVISION_v7).run();
622         runDeviceTests(PKG, CLASS, "testRevision0_12");
623     }
624 
625     @Test
626     @AppModeFull(reason = "'full' portion of the hostside test")
testDiffRevisionInheritBase_full()627     public void testDiffRevisionInheritBase_full() throws Exception {
628         testDiffRevisionInheritBase(false);
629     }
630     @Test
631     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDiffRevisionInheritBase_instant()632     public void testDiffRevisionInheritBase_instant() throws Exception {
633         testDiffRevisionInheritBase(true);
634     }
testDiffRevisionInheritBase(boolean instant)635     private void testDiffRevisionInheritBase(boolean instant) throws Exception {
636         new InstallMultiple(instant).addFile(APK).addFile(APK_v7).run();
637         runDeviceTests(PKG, CLASS, "testRevision0_0");
638         new InstallMultiple(instant).inheritFrom(PKG).addFile(APK_DIFF_REVISION_v7).run();
639         runDeviceTests(PKG, CLASS, "testRevision0_12");
640     }
641 
642     @Test
643     @AppModeFull(reason = "'full' portion of the hostside test")
testDiffRevisionInheritSplit_full()644     public void testDiffRevisionInheritSplit_full() throws Exception {
645         testDiffRevisionInheritSplit(false);
646     }
647     @Test
648     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDiffRevisionInheritSplit_instant()649     public void testDiffRevisionInheritSplit_instant() throws Exception {
650         testDiffRevisionInheritSplit(true);
651     }
testDiffRevisionInheritSplit(boolean instant)652     private void testDiffRevisionInheritSplit(boolean instant) throws Exception {
653         new InstallMultiple(instant).addFile(APK).addFile(APK_v7).run();
654         runDeviceTests(PKG, CLASS, "testRevision0_0");
655         new InstallMultiple(instant).inheritFrom(PKG).addFile(APK_DIFF_REVISION).run();
656         runDeviceTests(PKG, CLASS, "testRevision12_0");
657     }
658 
659     @Test
660     @AppModeFull(reason = "'full' portion of the hostside test")
testDiffRevisionDowngrade_full()661     public void testDiffRevisionDowngrade_full() throws Exception {
662         testDiffRevisionDowngrade(false);
663     }
664     @Test
665     @AppModeInstant(reason = "'instant' portion of the hostside test")
testDiffRevisionDowngrade_instant()666     public void testDiffRevisionDowngrade_instant() throws Exception {
667         testDiffRevisionDowngrade(true);
668     }
testDiffRevisionDowngrade(boolean instant)669     private void testDiffRevisionDowngrade(boolean instant) throws Exception {
670         new InstallMultiple(instant).addFile(APK).addFile(APK_DIFF_REVISION_v7).run();
671         new InstallMultiple(instant).inheritFrom(PKG).addFile(APK_v7).runExpectingFailure();
672     }
673 
674     @Test
675     @AppModeFull(reason = "'full' portion of the hostside test")
testFeatureWarmBase_full()676     public void testFeatureWarmBase_full() throws Exception {
677         testFeatureWarmBase(false);
678     }
679     @Test
680     @AppModeInstant(reason = "'instant' portion of the hostside test")
testFeatureWarmBase_instant()681     public void testFeatureWarmBase_instant() throws Exception {
682         testFeatureWarmBase(true);
683     }
testFeatureWarmBase(boolean instant)684     private void testFeatureWarmBase(boolean instant) throws Exception {
685         new InstallMultiple(instant).addFile(APK).addFile(APK_FEATURE_WARM).run();
686         runDeviceTests(PKG, CLASS, "testFeatureWarmBase");
687     }
688 
689     @Test
690     @AppModeFull(reason = "'full' portion of the hostside test")
testFeatureWarmApi_full()691     public void testFeatureWarmApi_full() throws Exception {
692         testFeatureWarmApi(false);
693     }
694     @Test
695     @AppModeInstant(reason = "'instant' portion of the hostside test")
testFeatureWarmApi_instant()696     public void testFeatureWarmApi_instant() throws Exception {
697         testFeatureWarmApi(true);
698     }
testFeatureWarmApi(boolean instant)699     private void testFeatureWarmApi(boolean instant) throws Exception {
700         new InstallMultiple(instant).addFile(APK).addFile(APK_FEATURE_WARM)
701                 .addFile(APK_FEATURE_WARM_v7).run();
702         runDeviceTests(PKG, CLASS, "testFeatureWarmApi");
703     }
704 
705     @Test
706     @AppModeFull(reason = "'full' portion of the hostside test")
testInheritUpdatedBase_full()707     public void testInheritUpdatedBase_full() throws Exception {
708         testInheritUpdatedBase(false);
709     }
710     @Test
711     @AppModeInstant(reason = "'instant' portion of the hostside test")
testInheritUpdatedBase_instant()712     public void testInheritUpdatedBase_instant() throws Exception {
713         testInheritUpdatedBase(true);
714     }
testInheritUpdatedBase(boolean instant)715     public void testInheritUpdatedBase(boolean instant) throws Exception {
716         new InstallMultiple(instant).addFile(APK).addFile(APK_FEATURE_WARM).run();
717         new InstallMultiple(instant).inheritFrom(PKG).addFile(APK_REVISION_A).run();
718         runDeviceTests(PKG, CLASS, "testInheritUpdatedBase_withRevisionA", instant);
719     }
720 
721     @Test
722     @AppModeFull(reason = "'full' portion of the hostside test")
testInheritUpdatedSplit_full()723     public void testInheritUpdatedSplit_full() throws Exception {
724         testInheritUpdatedSplit(false);
725     }
726     @Test
727     @AppModeInstant(reason = "'instant' portion of the hostside test")
testInheritUpdatedSplit_instant()728     public void testInheritUpdatedSplit_instant() throws Exception {
729         testInheritUpdatedSplit(true);
730     }
testInheritUpdatedSplit(boolean instant)731     private void testInheritUpdatedSplit(boolean instant) throws Exception {
732         new InstallMultiple(instant).addFile(APK).addFile(APK_FEATURE_WARM).run();
733         new InstallMultiple(instant).inheritFrom(PKG).addFile(APK_FEATURE_WARM_REVISION_A).run();
734         runDeviceTests(PKG, CLASS, "testInheritUpdatedSplit_withRevisionA", instant);
735     }
736 
737     @Test
738     @AppModeFull(reason = "'full' portion of the hostside test")
testFeatureWithoutRestart_full()739     public void testFeatureWithoutRestart_full() throws Exception {
740         testFeatureWithoutRestart(false);
741     }
742     @Test
743     @AppModeInstant(reason = "'instant' portion of the hostside test")
testFeatureWithoutRestart_instant()744     public void testFeatureWithoutRestart_instant() throws Exception {
745         testFeatureWithoutRestart(true);
746     }
testFeatureWithoutRestart(boolean instant)747     private void testFeatureWithoutRestart(boolean instant) throws Exception {
748         // always install as a full app; we're testing that the instant app can be
749         // updated without restarting and need a broadcast receiver to ensure the
750         // correct behaviour. So, this component must be visible to instant apps.
751         new InstallMultiple().addFile(APK).run();
752 
753         new InstallMultiple(instant).addFile(APK_NO_RESTART_BASE).run();
754         runDeviceTests(PKG, CLASS, "testBaseInstalled", instant);
755         new InstallMultiple(instant)
756                 .addArg("--dont-kill")
757                 .inheritFrom(PKG_NO_RESTART)
758                 .addFile(APK_NO_RESTART_FEATURE)
759                 .run();
760         runDeviceTests(PKG, CLASS, "testFeatureInstalled", instant);
761     }
762 
763     @Test
764     @AppModeFull(reason = "'full' portion of the hostside test")
testRequiredSplitMissing_full()765     public void testRequiredSplitMissing_full() throws Exception {
766         testRequiredSplitMissing(false);
767     }
768     @Test
769     @AppModeInstant(reason = "'instant' portion of the hostside test")
testRequiredSplitMissing_instant()770     public void testRequiredSplitMissing_instant() throws Exception {
771         testRequiredSplitMissing(true);
772     }
testRequiredSplitMissing(boolean instant)773     private void testRequiredSplitMissing(boolean instant) throws Exception {
774         new InstallMultiple(instant).addFile(APK_NEED_SPLIT_BASE)
775                 .runExpectingFailure("INSTALL_FAILED_MISSING_SPLIT");
776     }
777 
778     @Test
779     @AppModeFull(reason = "'full' portion of the hostside test")
testRequiredSplitInstalledFeatureWarm_full()780     public void testRequiredSplitInstalledFeatureWarm_full() throws Exception {
781         testRequiredSplitInstalledFeatureWarm(false);
782     }
783     @Test
784     @AppModeInstant(reason = "'instant' portion of the hostside test")
testRequiredSplitInstalledFeatureWarm_instant()785     public void testRequiredSplitInstalledFeatureWarm_instant() throws Exception {
786         testRequiredSplitInstalledFeatureWarm(true);
787     }
testRequiredSplitInstalledFeatureWarm(boolean instant)788     private void testRequiredSplitInstalledFeatureWarm(boolean instant) throws Exception {
789         new InstallMultiple(instant).addFile(APK_NEED_SPLIT_BASE)
790                 .addFile(APK_NEED_SPLIT_FEATURE_WARM).run();
791     }
792 
793     @Test
794     @AppModeFull(reason = "'full' portion of the hostside test")
testRequiredSplitInstalledConfig_full()795     public void testRequiredSplitInstalledConfig_full() throws Exception {
796         testRequiredSplitInstalledConfig(false);
797     }
798     @Test
799     @AppModeInstant(reason = "'instant' portion of the hostside test")
testRequiredSplitInstalledConfig_instant()800     public void testRequiredSplitInstalledConfig_instant() throws Exception {
801         testRequiredSplitInstalledConfig(true);
802     }
testRequiredSplitInstalledConfig(boolean instant)803     private void testRequiredSplitInstalledConfig(boolean instant) throws Exception {
804         new InstallMultiple(instant).addFile(APK_NEED_SPLIT_BASE).addFile(APK_NEED_SPLIT_CONFIG)
805                 .run();
806     }
807 
808     @Test
809     @AppModeFull(reason = "'full' portion of the hostside test")
testRequiredSplitRemoved_full()810     public void testRequiredSplitRemoved_full() throws Exception {
811         testRequiredSplitRemoved(false);
812     }
813     @Test
814     @AppModeInstant(reason = "'instant' portion of the hostside test")
testRequiredSplitRemoved_instant()815     public void testRequiredSplitRemoved_instant() throws Exception {
816         testRequiredSplitRemoved(true);
817     }
testRequiredSplitRemoved(boolean instant)818     private void testRequiredSplitRemoved(boolean instant) throws Exception {
819         // start with a base and two splits
820         new InstallMultiple(instant)
821                 .addFile(APK_NEED_SPLIT_BASE)
822                 .addFile(APK_NEED_SPLIT_FEATURE_WARM)
823                 .addFile(APK_NEED_SPLIT_CONFIG)
824                 .run();
825         // it's okay to remove one of the splits
826         new InstallMultiple(instant).inheritFrom(PKG).removeSplit("feature_warm").run();
827         // but, not to remove all of them
828         new InstallMultiple(instant).inheritFrom(PKG).removeSplit("config.xxhdpi")
829                 .runExpectingFailure("INSTALL_FAILED_MISSING_SPLIT");
830     }
831 
832     @Test
833     @AppModeFull(reason = "'full' portion of the hostside test")
testRequiredSplitTypesInstalledIncomplete_full()834     public void testRequiredSplitTypesInstalledIncomplete_full() throws Exception {
835         testRequiredSplitTypesInstalledIncomplete(false);
836     }
837     @Test
838     @AppModeInstant(reason = "'instant' portion of the hostside test")
testRequiredSplitTypesInstalledIncomplete_instant()839     public void testRequiredSplitTypesInstalledIncomplete_instant() throws Exception {
840         testRequiredSplitTypesInstalledIncomplete(true);
841     }
testRequiredSplitTypesInstalledIncomplete(boolean instant)842     private void testRequiredSplitTypesInstalledIncomplete(boolean instant) throws Exception {
843         new InstallMultiple(instant).addFile(APK_REQUIRED_SPLIT_TYPE_BASE)
844                 .addFile(APK_REQUIRED_SPLIT_TYPE_LOCALE)
845                 .runExpectingFailure("INSTALL_FAILED_MISSING_SPLIT");
846     }
847 
848     @Test
849     @AppModeFull(reason = "'full' portion of the hostside test")
testInvalidRequiredSplitTypes_full()850     public void testInvalidRequiredSplitTypes_full() throws Exception {
851         testInvalidRequiredSplitTypes(false);
852     }
853     @Test
854     @AppModeInstant(reason = "'instant' portion of the hostside test")
testInvalidRequiredSplitTypes_instant()855     public void testInvalidRequiredSplitTypes_instant() throws Exception {
856         testInvalidRequiredSplitTypes(true);
857     }
testInvalidRequiredSplitTypes(boolean instant)858     private void testInvalidRequiredSplitTypes(boolean instant) throws Exception {
859         new InstallMultiple(instant).addFile(APK_INVALID_REQUIRED_SPLIT_TYPE_BASE)
860                 .runExpectingFailure("INSTALL_PARSE_FAILED_MANIFEST_MALFORMED");
861     }
862 
863     @Test
864     @AppModeFull(reason = "'full' portion of the hostside test")
testRequiredSplitTypesInstalledAll_full()865     public void testRequiredSplitTypesInstalledAll_full() throws Exception {
866         testRequiredSplitTypesInstalledAll(false);
867     }
868     @Test
869     @AppModeInstant(reason = "'instant' portion of the hostside test")
testRequiredSplitTypesInstalledAll_instant()870     public void testRequiredSplitTypesInstalledAll_instant() throws Exception {
871         testRequiredSplitTypesInstalledAll(true);
872     }
testRequiredSplitTypesInstalledAll(boolean instant)873     private void testRequiredSplitTypesInstalledAll(boolean instant) throws Exception {
874         new InstallMultiple(instant).addFile(APK_REQUIRED_SPLIT_TYPE_BASE)
875                 .addFile(APK_REQUIRED_SPLIT_TYPE_DENSITY)
876                 .addFile(APK_REQUIRED_SPLIT_TYPE_LOCALE)
877                 .run();
878     }
879 
880     @Test
881     @AppModeFull(reason = "'full' portion of the hostside test")
testRequiredSplitTypesInstalledMultipleOne_full()882     public void testRequiredSplitTypesInstalledMultipleOne_full() throws Exception {
883         testRequiredSplitTypesInstalledMultipleOne(false);
884     }
885     @Test
886     @AppModeInstant(reason = "'instant' portion of the hostside test")
testRequiredSplitTypesInstalledMultipleOne_instant()887     public void testRequiredSplitTypesInstalledMultipleOne_instant() throws Exception {
888         testRequiredSplitTypesInstalledMultipleOne(true);
889     }
testRequiredSplitTypesInstalledMultipleOne(boolean instant)890     private void testRequiredSplitTypesInstalledMultipleOne(boolean instant) throws Exception {
891         new InstallMultiple(instant).addFile(APK_REQUIRED_SPLIT_TYPE_BASE)
892                 .addFile(APK_REQUIRED_SPLIT_TYPE_MULTIPLE)
893                 .run();
894     }
895 
896     @Test
897     @AppModeFull(reason = "'full' portion of the hostside test")
testRequiredSplitTypesRemoved_full()898     public void testRequiredSplitTypesRemoved_full() throws Exception {
899         testRequiredSplitTypesRemoved(false);
900     }
901     @Test
902     @AppModeInstant(reason = "'instant' portion of the hostside test")
testRequiredSplitTypesRemoved_instant()903     public void testRequiredSplitTypesRemoved_instant() throws Exception {
904         testRequiredSplitTypesRemoved(true);
905     }
testRequiredSplitTypesRemoved(boolean instant)906     private void testRequiredSplitTypesRemoved(boolean instant) throws Exception {
907         // start with a base and three splits
908         new InstallMultiple(instant)
909                 .addFile(APK_REQUIRED_SPLIT_TYPE_BASE)
910                 .addFile(APK_REQUIRED_SPLIT_TYPE_DENSITY)
911                 .addFile(APK_REQUIRED_SPLIT_TYPE_LOCALE)
912                 .addFile(APK_REQUIRED_SPLIT_TYPE_FOO)
913                 .run();
914         // it's okay to remove non-required split type
915         new InstallMultiple(instant).inheritFrom(PKG).removeSplit("config.foo").run();
916         // but, not to remove a required one
917         new InstallMultiple(instant).inheritFrom(PKG).removeSplit("config.de")
918                 .runExpectingFailure("INSTALL_FAILED_MISSING_SPLIT");
919     }
920 
921     @Test
922     @AppModeFull(reason = "'full' portion of the hostside test")
testInheritUpdatedBase_requiredSplitTypesMissing_full()923     public void testInheritUpdatedBase_requiredSplitTypesMissing_full() throws Exception {
924         testInheritUpdatedBase_requiredSplitTypesMissing(false);
925     }
926     @Test
927     @AppModeInstant(reason = "'instant' portion of the hostside test")
testInheritUpdatedBase_requiredSplitTypesMissing_instant()928     public void testInheritUpdatedBase_requiredSplitTypesMissing_instant() throws Exception {
929         testInheritUpdatedBase_requiredSplitTypesMissing(true);
930     }
testInheritUpdatedBase_requiredSplitTypesMissing(boolean instant)931     private void testInheritUpdatedBase_requiredSplitTypesMissing(boolean instant)
932             throws Exception {
933         // start with a base and the required splits
934         new InstallMultiple(instant)
935                 .addFile(APK_REQUIRED_SPLIT_TYPE_BASE)
936                 .addFile(APK_REQUIRED_SPLIT_TYPE_DENSITY)
937                 .addFile(APK_REQUIRED_SPLIT_TYPE_LOCALE)
938                 .run();
939         // the updated base requires a new split type, but it's missing
940         new InstallMultiple(instant).inheritFrom(PKG).addFile(APK_REQUIRED_SPLIT_TYPE_BASE_UPDATED)
941                 .runExpectingFailure("INSTALL_FAILED_MISSING_SPLIT");
942     }
943 
944     @Test
945     @AppModeFull(reason = "'full' portion of the hostside test")
testInheritUpdatedBase_requiredSplitTypesInstalled_full()946     public void testInheritUpdatedBase_requiredSplitTypesInstalled_full() throws Exception {
947         testInheritUpdatedBase_requiredSplitTypesInstalled(false);
948     }
949     @Test
950     @AppModeInstant(reason = "'instant' portion of the hostside test")
testInheritUpdatedBase_requiredSplitTypesInstalled_instant()951     public void testInheritUpdatedBase_requiredSplitTypesInstalled_instant() throws Exception {
952         testInheritUpdatedBase_requiredSplitTypesInstalled(true);
953     }
testInheritUpdatedBase_requiredSplitTypesInstalled(boolean instant)954     private void testInheritUpdatedBase_requiredSplitTypesInstalled(boolean instant)
955             throws Exception {
956         // start with a base and the required splits
957         new InstallMultiple(instant)
958                 .addFile(APK_REQUIRED_SPLIT_TYPE_BASE)
959                 .addFile(APK_REQUIRED_SPLIT_TYPE_DENSITY)
960                 .addFile(APK_REQUIRED_SPLIT_TYPE_LOCALE)
961                 .run();
962         // the updated base requires a split type, and this split also requires another.
963         new InstallMultiple(instant).inheritFrom(PKG)
964                 .addFile(APK_REQUIRED_SPLIT_TYPE_BASE_UPDATED)
965                 .addFile(APK_REQUIRED_SPLIT_TYPE_FEATURE)
966                 .addFile(APK_REQUIRED_SPLIT_TYPE_FEATURE_DATA)
967                 .run();
968     }
969 
970     @Test
971     @AppModeFull(reason = "'full' portion of the hostside test")
testRequiredSplitTypesFromSplit_full()972     public void testRequiredSplitTypesFromSplit_full() throws Exception {
973         testRequiredSplitTypesFromSplit(false);
974     }
975     @Test
976     @AppModeInstant(reason = "'instant' portion of the hostside test")
testRequiredSplitTypesFromSplit_instant()977     public void testRequiredSplitTypesFromSplit_instant() throws Exception {
978         testRequiredSplitTypesFromSplit(true);
979     }
testRequiredSplitTypesFromSplit(boolean instant)980     private void testRequiredSplitTypesFromSplit(boolean instant) throws Exception {
981         new InstallMultiple(instant)
982                 .addFile(APK_REQUIRED_SPLIT_TYPE_BASE)
983                 .addFile(APK_REQUIRED_SPLIT_TYPE_DENSITY)
984                 .addFile(APK_REQUIRED_SPLIT_TYPE_LOCALE)
985                 .addFile(APK_REQUIRED_SPLIT_TYPE_FEATURE)
986                 .addFile(APK_REQUIRED_SPLIT_TYPE_FEATURE_DATA)
987                 .addFile(APK_REQUIRED_SPLIT_TYPE_FEATURE_FOO)
988                 .run();
989         // it's okay to remove non-required split type for the split
990         new InstallMultiple(instant).inheritFrom(PKG).removeSplit("feature_foo.foo").run();
991         // but, not to remove a required one for the split
992         new InstallMultiple(instant).inheritFrom(PKG).removeSplit("feature_foo.data")
993                 .runExpectingFailure("INSTALL_FAILED_MISSING_SPLIT");
994     }
995 
996     /**
997      * Verify that installing a new version of app wipes code cache.
998      */
999     @Test
1000     @AppModeFull(reason = "'full' portion of the hostside test")
testClearCodeCache_full()1001     public void testClearCodeCache_full() throws Exception {
1002         testClearCodeCache(false);
1003     }
1004     @Test
1005     @AppModeInstant(reason = "'instant' portion of the hostside test")
testClearCodeCache_instant()1006     public void testClearCodeCache_instant() throws Exception {
1007         testClearCodeCache(true);
1008     }
testClearCodeCache(boolean instant)1009     private void testClearCodeCache(boolean instant) throws Exception {
1010         new InstallMultiple(instant).addFile(APK).run();
1011         runDeviceTests(PKG, CLASS, "testCodeCacheWrite");
1012         new InstallMultiple(instant).addArg("-r").addFile(APK_DIFF_VERSION).run();
1013         runDeviceTests(PKG, CLASS, "testCodeCacheRead");
1014     }
1015 
1016     @Test
1017     @AppModeInstant(reason = "'instant' portion of the hostside test")
testComponentWithSplitName_instant()1018     public void testComponentWithSplitName_instant() throws Exception {
1019         new InstallMultiple(true).addFile(APK_INSTANT).run();
1020         runDeviceTests(PKG, CLASS, "testComponentWithSplitName_singleBase");
1021         new InstallMultiple(true).inheritFrom(PKG).addFile(APK_FEATURE_WARM).run();
1022         runDeviceTests(PKG, CLASS, "testComponentWithSplitName_featureWarmInstalled");
1023     }
1024 
1025     @Test
1026     @AppModeFull(reason = "'full' portion of the hostside test")
testTheme_installBase_full()1027     public void testTheme_installBase_full() throws Exception {
1028         testTheme_installBase(false);
1029     }
1030     @Test
1031     @AppModeInstant(reason = "'instant' portion of the hostside test")
testTheme_installBase_instant()1032     public void testTheme_installBase_instant() throws Exception {
1033         testTheme_installBase(true);
1034     }
testTheme_installBase(boolean instant)1035     private void testTheme_installBase(boolean instant) throws Exception {
1036         new InstallMultiple(instant).addFile(APK).run();
1037         runDeviceTests(PKG, CLASS, "launchBaseActivity_withThemeBase_baseApplied");
1038     }
1039 
1040     @Test
1041     @AppModeFull(reason = "'full' portion of the hostside test")
testTheme_installBaseV23_full()1042     public void testTheme_installBaseV23_full() throws Exception {
1043         testTheme_installBaseV23(false);
1044     }
1045     @Test
1046     @AppModeInstant(reason = "'instant' portion of the hostside test")
testTheme_installBaseV23_instant()1047     public void testTheme_installBaseV23_instant() throws Exception {
1048         testTheme_installBaseV23(true);
1049     }
testTheme_installBaseV23(boolean instant)1050     private void testTheme_installBaseV23(boolean instant) throws Exception {
1051         new InstallMultiple(instant).addFile(APK).addFile(APK_v23).run();
1052         runDeviceTests(PKG, CLASS, "launchBaseActivity_withThemeBaseLt_baseLtApplied");
1053     }
1054 
1055     @Test
1056     @AppModeFull(reason = "'full' portion of the hostside test")
testTheme_installFeatureWarm_full()1057     public void testTheme_installFeatureWarm_full() throws Exception {
1058         testTheme_installFeatureWarm(false);
1059     }
1060     @Test
1061     @AppModeInstant(reason = "'instant' portion of the hostside test")
testTheme_installFeatureWarm_instant()1062     public void testTheme_installFeatureWarm_instant() throws Exception {
1063         testTheme_installFeatureWarm(true);
1064     }
testTheme_installFeatureWarm(boolean instant)1065     private void testTheme_installFeatureWarm(boolean instant) throws Exception {
1066         new InstallMultiple(instant).addFile(APK).addFile(APK_FEATURE_WARM).run();
1067         runDeviceTests(PKG, CLASS, "launchBaseActivity_withThemeWarm_warmApplied");
1068         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeBase_baseApplied");
1069         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeWarm_warmApplied");
1070     }
1071 
1072     @Test
1073     @AppModeFull(reason = "'full' portion of the hostside test")
testTheme_installFeatureWarmV23_full()1074     public void testTheme_installFeatureWarmV23_full() throws Exception {
1075         testTheme_installFeatureWarmV23(false);
1076     }
1077     @Test
1078     @AppModeInstant(reason = "'instant' portion of the hostside test")
testTheme_installFeatureWarmV23_instant()1079     public void testTheme_installFeatureWarmV23_instant() throws Exception {
1080         testTheme_installFeatureWarmV23(true);
1081     }
testTheme_installFeatureWarmV23(boolean instant)1082     private void testTheme_installFeatureWarmV23(boolean instant) throws Exception {
1083         new InstallMultiple(instant).addFile(APK).addFile(APK_v23).addFile(APK_FEATURE_WARM)
1084                 .addFile(APK_FEATURE_WARM_v23).run();
1085         runDeviceTests(PKG, CLASS, "launchBaseActivity_withThemeWarmLt_warmLtApplied");
1086         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeBaseLt_baseLtApplied");
1087         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeWarmLt_warmLtApplied");
1088     }
1089 
1090     @Test
1091     @AppModeFull(reason = "'full' portion of the hostside test")
testTheme_installFeatureWarmV23_removeV23_full()1092     public void testTheme_installFeatureWarmV23_removeV23_full() throws Exception {
1093         testTheme_installFeatureWarmV23_removeV23(false);
1094     }
1095     @Test
1096     @AppModeInstant(reason = "'instant' portion of the hostside test")
testTheme_installFeatureWarmV23_removeV23_instant()1097     public void testTheme_installFeatureWarmV23_removeV23_instant() throws Exception {
1098         testTheme_installFeatureWarmV23_removeV23(true);
1099     }
testTheme_installFeatureWarmV23_removeV23(boolean instant)1100     private void testTheme_installFeatureWarmV23_removeV23(boolean instant) throws Exception {
1101         new InstallMultiple(instant).addFile(APK).addFile(APK_v23).addFile(APK_FEATURE_WARM)
1102                 .addFile(APK_FEATURE_WARM_v23).run();
1103         new InstallMultiple(instant).inheritFrom(PKG).removeSplit("config.v23")
1104                 .removeSplit("feature_warm.config.v23").run();
1105         runDeviceTests(PKG, CLASS, "launchBaseActivity_withThemeWarm_warmApplied");
1106         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeBase_baseApplied");
1107         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeWarm_warmApplied");
1108     }
1109 
1110     @Test
1111     @AppModeFull(reason = "'full' portion of the hostside test")
testTheme_installFeatureWarmAndRose_full()1112     public void testTheme_installFeatureWarmAndRose_full() throws Exception {
1113         testTheme_installFeatureWarmAndRose(false);
1114     }
1115     @Test
1116     @AppModeInstant(reason = "'instant' portion of the hostside test")
testTheme_installFeatureWarmAndRose_instant()1117     public void testTheme_installFeatureWarmAndRose_instant() throws Exception {
1118         testTheme_installFeatureWarmAndRose(true);
1119     }
testTheme_installFeatureWarmAndRose(boolean instant)1120     private void testTheme_installFeatureWarmAndRose(boolean instant) throws Exception {
1121         new InstallMultiple(instant).addFile(APK).addFile(APK_FEATURE_WARM)
1122                 .addFile(APK_FEATURE_ROSE).run();
1123         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeWarm_warmApplied");
1124         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeRose_roseApplied");
1125         runDeviceTests(PKG, CLASS, "launchRoseActivity_withThemeWarm_warmApplied");
1126         runDeviceTests(PKG, CLASS, "launchRoseActivity_withThemeRose_roseApplied");
1127     }
1128 
1129     @Test
1130     @AppModeFull(reason = "'full' portion of the hostside test")
testTheme_installFeatureWarmAndRoseV23_full()1131     public void testTheme_installFeatureWarmAndRoseV23_full() throws Exception {
1132         testTheme_installFeatureWarmAndRoseV23(false);
1133     }
1134     @Test
1135     @AppModeInstant(reason = "'instant' portion of the hostside test")
testTheme_installFeatureWarmAndRoseV23_instant()1136     public void testTheme_installFeatureWarmAndRoseV23_instant() throws Exception {
1137         testTheme_installFeatureWarmAndRoseV23(true);
1138     }
testTheme_installFeatureWarmAndRoseV23(boolean instant)1139     private void testTheme_installFeatureWarmAndRoseV23(boolean instant) throws Exception {
1140         new InstallMultiple(instant).addFile(APK).addFile(APK_v23)
1141                 .addFile(APK_FEATURE_WARM).addFile(APK_FEATURE_WARM_v23)
1142                 .addFile(APK_FEATURE_ROSE).addFile(APK_FEATURE_ROSE_v23).run();
1143         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeWarmLt_warmLtApplied");
1144         runDeviceTests(PKG, CLASS, "launchWarmActivity_withThemeRoseLt_roseLtApplied");
1145         runDeviceTests(PKG, CLASS, "launchRoseActivity_withThemeWarmLt_warmLtApplied");
1146         runDeviceTests(PKG, CLASS, "launchRoseActivity_withThemeRoseLt_roseLtApplied");
1147     }
1148 }
1149