1 /*
2  * Copyright (C) 2020 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 com.android.tests.apex;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assume.assumeTrue;
22 
23 import android.cts.install.lib.host.InstallUtilsHost;
24 
25 import com.android.compatibility.common.util.CpuFeatures;
26 import com.android.internal.util.test.SystemPreparer;
27 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
28 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
29 
30 import org.junit.Rule;
31 import org.junit.Test;
32 import org.junit.rules.RuleChain;
33 import org.junit.rules.TemporaryFolder;
34 import org.junit.runner.RunWith;
35 
36 import java.time.Duration;
37 
38 @RunWith(DeviceJUnit4ClassRunner.class)
39 public class SharedLibsApexTest extends BaseHostJUnit4Test {
40 
41     private final InstallUtilsHost mHostUtils = new InstallUtilsHost(this);
42     private final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
43     private final SystemPreparer mPreparer = new SystemPreparer(mTemporaryFolder,
44             this::getDevice);
45 
46     @Rule
47     public final RuleChain ruleChain = RuleChain.outerRule(mTemporaryFolder).around(mPreparer);
48 
49     enum ApexName {
50         FOO,
51         BAR,
52         BAZ,
53         PONY,
54         SHAREDLIBS,
55         SHAREDLIBS_SECONDARY
56     }
57 
58     enum ApexVersion {
59         ONE,
60         TWO
61     }
62 
63     enum ApexType {
64         DEFAULT,
65         STRIPPED
66     }
67 
68     enum SharedLibsVersion {
69         X,
70         Y,
71         Z
72     }
73 
74     /**
75      * Utility function to generate test apex names in the form e.g.:
76      *   "com.android.apex.test.bar.v1.libvX.apex"
77      */
getTestApex(ApexName apexName, ApexType apexType, ApexVersion apexVersion, SharedLibsVersion sharedLibsVersion)78     private String getTestApex(ApexName apexName, ApexType apexType, ApexVersion apexVersion,
79             SharedLibsVersion sharedLibsVersion) {
80         StringBuilder ret = new StringBuilder();
81         ret.append("com.android.apex.test.");
82         switch(apexName) {
83             case FOO:
84                 ret.append("foo");
85                 break;
86             case BAR:
87                 ret.append("bar");
88                 break;
89             case BAZ:
90                 ret.append("baz");
91                 break;
92             case PONY:
93                 ret.append("pony");
94                 break;
95             case SHAREDLIBS:
96                 ret.append("sharedlibs_generated");
97                 break;
98             case SHAREDLIBS_SECONDARY:
99                 ret.append("sharedlibs_secondary_generated");
100                 break;
101         }
102 
103         switch(apexType) {
104             case STRIPPED:
105                 ret.append("_stripped");
106                 break;
107             case DEFAULT:
108                 break;
109         }
110 
111         switch(apexVersion) {
112             case ONE:
113                 ret.append(".v1");
114                 break;
115             case TWO:
116                 ret.append(".v2");
117                 break;
118         }
119 
120         switch(sharedLibsVersion) {
121             case X:
122                 ret.append(".libvX.apex");
123                 break;
124             case Y:
125                 ret.append(".libvY.apex");
126                 break;
127             case Z:
128                 ret.append(".libvZ.apex");
129                 break;
130         }
131 
132         return ret.toString();
133     }
134 
135     /**
136      * Utility function to generate the file name of an installed package as per
137      * apexd convention e.g.: "com.android.apex.test.bar@1.apex"
138      */
getInstalledApexFileName(ApexName apexName, ApexVersion apexVersion)139     private String getInstalledApexFileName(ApexName apexName, ApexVersion apexVersion) {
140         StringBuilder ret = new StringBuilder();
141         ret.append("com.android.apex.test.");
142         switch(apexName) {
143             case FOO:
144                 ret.append("foo");
145                 break;
146             case BAR:
147                 ret.append("bar");
148                 break;
149             case BAZ:
150                 ret.append("baz");
151                 break;
152             case PONY:
153                 ret.append("pony");
154                 break;
155             case SHAREDLIBS:
156                 ret.append("sharedlibs");
157                 break;
158             case SHAREDLIBS_SECONDARY:
159                 ret.append("sharedlibs_secondary");
160                 break;
161         }
162         ret.append("@");
163         switch(apexVersion) {
164             case ONE:
165                 ret.append("1");
166                 break;
167             case TWO:
168                 ret.append("2");
169                 break;
170         }
171         ret.append(".apex");
172         return ret.toString();
173     }
174 
175     /**
176      * Tests basic functionality of two apex packages being force-installed and the C++ binaries
177      * contained in them being executed correctly.
178      */
179     @Test
testInstallAndRunDefaultApexs()180     public void testInstallAndRunDefaultApexs() throws Exception {
181         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
182         assumeTrue("Device requires root", getDevice().isAdbRoot());
183 
184         for (String apex : new String[]{
185                 getTestApex(ApexName.BAR, ApexType.DEFAULT, ApexVersion.ONE, SharedLibsVersion.X),
186                 getTestApex(ApexName.FOO, ApexType.DEFAULT, ApexVersion.ONE, SharedLibsVersion.X),
187                 getTestApex(ApexName.PONY, ApexType.DEFAULT, ApexVersion.ONE, SharedLibsVersion.Z),
188         }) {
189             mPreparer.pushResourceFile(apex,
190                     "/system/apex/" + apex);
191         }
192         mPreparer.reboot();
193 
194         getDevice().disableAdbRoot();
195         String runAsResult = getDevice().executeShellCommand(
196                 "/apex/com.android.apex.test.foo/bin/foo_test");
197         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
198         if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) {
199             runAsResult = getDevice().executeShellCommand(
200                     "/apex/com.android.apex.test.bar/bin/bar_test32");
201             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
202         }
203         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
204             runAsResult = getDevice().executeShellCommand(
205                     "/apex/com.android.apex.test.bar/bin/bar_test64");
206             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
207         }
208         runAsResult = getDevice().executeShellCommand(
209                 "/apex/com.android.apex.test.pony/bin/pony_test");
210         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
211 
212         mPreparer.stageMultiplePackages(
213             new String[]{
214                 getTestApex(ApexName.BAR, ApexType.DEFAULT, ApexVersion.TWO, SharedLibsVersion.Y),
215                 getTestApex(ApexName.FOO, ApexType.DEFAULT, ApexVersion.TWO, SharedLibsVersion.Y),
216             },
217             new String[] {
218                 "com.android.apex.test.bar",
219                 "com.android.apex.test.foo",
220             }).reboot();
221 
222         runAsResult = getDevice().executeShellCommand(
223             "/apex/com.android.apex.test.foo/bin/foo_test");
224         assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y");
225         if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) {
226             runAsResult = getDevice().executeShellCommand(
227                 "/apex/com.android.apex.test.bar/bin/bar_test32");
228             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
229         }
230         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
231             runAsResult = getDevice().executeShellCommand(
232                 "/apex/com.android.apex.test.bar/bin/bar_test64");
233             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
234         }
235     }
236 
237     /**
238      * Tests functionality of shared libraries apex: installs two apexs "stripped" of libc++.so and
239      * one apex containing it and verifies that C++ binaries can run.
240      */
241     @Test
testInstallAndRunOptimizedApexs()242     public void testInstallAndRunOptimizedApexs() throws Exception {
243         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
244         assumeTrue("Device requires root", getDevice().isAdbRoot());
245 
246         // Base case:
247         //
248         // Pre-installed on /system:
249         //   package bar version 1 using library version X
250         //   package foo version 1 using library version X
251         //   package sharedlibs version 1 exporting library version X
252         //
253         //   package pony version 1 using library version Z
254         //   package sharedlibs_secondary version 1 exporting library version Z
255 
256         for (String apex : new String[]{
257                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
258                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
259                 getTestApex(ApexName.PONY, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.Z),
260                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
261                     SharedLibsVersion.X),
262                 getTestApex(ApexName.SHAREDLIBS_SECONDARY, ApexType.DEFAULT, ApexVersion.ONE,
263                     SharedLibsVersion.Z),
264         }) {
265             mPreparer.pushResourceFile(apex,
266                     "/system/apex/" + apex);
267         }
268         mPreparer.reboot();
269 
270         getDevice().disableAdbRoot();
271         String runAsResult = getDevice().executeShellCommand(
272                 "/apex/com.android.apex.test.foo/bin/foo_test");
273         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
274         if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) {
275             runAsResult = getDevice().executeShellCommand(
276                     "/apex/com.android.apex.test.bar/bin/bar_test32");
277             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
278         }
279         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
280             runAsResult = getDevice().executeShellCommand(
281                     "/apex/com.android.apex.test.bar/bin/bar_test64");
282             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
283         }
284         runAsResult = getDevice().executeShellCommand(
285                 "/apex/com.android.apex.test.pony/bin/pony_test");
286         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
287 
288         // Edge case: sharedlibs updated with a same version apex.
289         //
290         // Updated packages (installed on /data/apex/active):
291         //   package sharedlibs version 1 exporting library version X            <-- new
292         //   package sharedlibs_secondary version 1 exporting library version Z  <-- new
293         //
294         // Pre-installed:
295         //   package bar version 1 using library version X
296         //   package foo version 1 using library version X
297         //   (inactive) package sharedlibs version 1 exporting library version X
298         //
299         //   package pony version 1 using library version Z
300         //   (inactive) package sharedlibs_secondary version 1 exporting library version Z
301 
302         mPreparer.stageMultiplePackages(
303             new String[]{
304                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
305                     SharedLibsVersion.X),
306                 getTestApex(ApexName.SHAREDLIBS_SECONDARY, ApexType.DEFAULT, ApexVersion.ONE,
307                     SharedLibsVersion.Z),
308             },
309             new String[]{
310                 "com.android.apex.test.sharedlibs",
311                 "com.android.apex.test.sharedlibs_secondary",
312             }).reboot();
313 
314         runAsResult = getDevice().executeShellCommand(
315                 "/apex/com.android.apex.test.foo/bin/foo_test");
316         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
317         if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) {
318             runAsResult = getDevice().executeShellCommand(
319                     "/apex/com.android.apex.test.bar/bin/bar_test32");
320             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
321         }
322         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
323             runAsResult = getDevice().executeShellCommand(
324                     "/apex/com.android.apex.test.bar/bin/bar_test64");
325             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
326         }
327         runAsResult = getDevice().executeShellCommand(
328                 "/apex/com.android.apex.test.pony/bin/pony_test");
329         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
330 
331         // Updated packages (installed on /data/apex/active):
332         //   package bar version 2 using library version Y               <-- new
333         //   package foo version 2 using library version Y               <-- new
334         //   package sharedlibs version 2 exporting library version Y    <-- new
335         //   package sharedlibs_secondary version 1 exporting library version Z
336         //
337         // Pre-installed:
338         //   (inactive) package bar version 1 using library version X
339         //   (inactive) package foo version 1 using library version X
340         //   package sharedlibs version 1 exporting library version X
341         //
342         //   package pony version 1 using library version Z
343         //   (inactive) package sharedlibs_secondary version 1 exporting library version Z
344 
345         mPreparer.stageMultiplePackages(
346             new String[]{
347                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y),
348                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y),
349                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.TWO,
350                     SharedLibsVersion.Y),
351             },
352             new String[]{
353                 "com.android.apex.test.bar",
354                 "com.android.apex.test.foo",
355                 "com.android.apex.test.sharedlibs",
356             }).reboot();
357 
358         runAsResult = getDevice().executeShellCommand(
359             "/apex/com.android.apex.test.foo/bin/foo_test");
360         assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y");
361         if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) {
362             runAsResult = getDevice().executeShellCommand(
363                 "/apex/com.android.apex.test.bar/bin/bar_test32");
364             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
365         }
366         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
367             runAsResult = getDevice().executeShellCommand(
368                 "/apex/com.android.apex.test.bar/bin/bar_test64");
369             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
370         }
371         runAsResult = getDevice().executeShellCommand(
372             "/apex/com.android.apex.test.pony/bin/pony_test");
373         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
374 
375         // Assume that an OTA now adds a package baz on /system needing libraries installed on
376         // /system:
377         //
378         // Updated packages (installed on /data/apex/active):
379         //   package bar version 2 using library version Y
380         //   package foo version 2 using library version Y
381         //   package sharedlibs version 2 exporting library version Y
382         //
383         // Pre-installed:
384         //   (inactive) package bar version 1 using library version X
385         //   package baz version 1 using library version X               <-- new
386         //   (inactive) package foo version 1 using library version X
387         //   package sharedlibs version 1 exporting library version X
388         //   package pony version 1 using library version Z
389         //   package sharedlibs_secondary version 1 exporting library version Z
390 
391         String baz_apex =
392                 getTestApex(ApexName.BAZ, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X);
393         mPreparer.pushResourceFile(baz_apex, "/system/apex/" + baz_apex);
394         mPreparer.reboot();
395 
396         runAsResult = getDevice().executeShellCommand(
397             "/apex/com.android.apex.test.foo/bin/foo_test");
398         assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y");
399         if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) {
400             runAsResult = getDevice().executeShellCommand(
401                 "/apex/com.android.apex.test.bar/bin/bar_test32");
402             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
403         }
404         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
405             runAsResult = getDevice().executeShellCommand(
406                 "/apex/com.android.apex.test.bar/bin/bar_test64");
407             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
408         }
409         runAsResult = getDevice().executeShellCommand(
410             "/apex/com.android.apex.test.baz/bin/baz_test");
411         assertThat(runAsResult).isEqualTo("BAZ_VERSION_1 SHARED_LIB_VERSION_X");
412         runAsResult = getDevice().executeShellCommand(
413                 "/apex/com.android.apex.test.pony/bin/pony_test");
414         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
415     }
416 
417     /**
418      * Tests that when a shared library apex is updated via OTA the previously
419      * downloaded version is remoted.
420      */
421     @Test
testHigherVersionOnSystemDeletesDataVersion()422     public void testHigherVersionOnSystemDeletesDataVersion() throws Exception {
423         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
424         assumeTrue("Device requires root", getDevice().isAdbRoot());
425 
426         // Base case:
427         //
428         // Pre-installed on /system:
429         //   package bar version 1 using library version X
430         //   package foo version 1 using library version X
431         //   package sharedlibs version 1 exporting library version X
432         for (String apex : new String[]{
433                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
434                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
435                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
436                     SharedLibsVersion.X),
437         }) {
438             mPreparer.pushResourceFile(apex,
439                     "/system/apex/" + apex);
440         }
441         mPreparer.reboot();
442         String runAsResult = getDevice().executeShellCommand(
443                 "/apex/com.android.apex.test.foo/bin/foo_test");
444         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
445         if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) {
446             runAsResult = getDevice().executeShellCommand(
447                     "/apex/com.android.apex.test.bar/bin/bar_test32");
448             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
449         }
450         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
451             runAsResult = getDevice().executeShellCommand(
452                     "/apex/com.android.apex.test.bar/bin/bar_test64");
453             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
454         }
455 
456         // Same-grade case:
457         //
458         // Pre-installed on /system:
459         //   package bar version 1 using library version X
460         //   package foo version 1 using library version X
461         //   package sharedlibs version 1 exporting library version X
462         // Updated packages (installed on /data/apex/active):
463         //   package bar version 1 using library version X
464         //   package foo version 1 using library version X
465         //   package sharedlibs version 1 exporting library version X
466         mPreparer.stageMultiplePackages(
467             new String[]{
468                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
469                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
470                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
471                     SharedLibsVersion.X),
472             },
473             new String[]{
474                 "com.android.apex.test.bar",
475                 "com.android.apex.test.foo",
476                 "com.android.apex.test.sharedlibs",
477             }).reboot();
478 
479         runAsResult = getDevice().executeShellCommand(
480                 "/apex/com.android.apex.test.foo/bin/foo_test");
481         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
482         if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) {
483             runAsResult = getDevice().executeShellCommand(
484                     "/apex/com.android.apex.test.bar/bin/bar_test32");
485             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
486         }
487         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
488             runAsResult = getDevice().executeShellCommand(
489                     "/apex/com.android.apex.test.bar/bin/bar_test64");
490             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
491         }
492 
493         // Simulate OTA upgrading pre-installed modules:
494         //
495         // Pre-installed on /system:
496         //   package bar version 2 using library version Y
497         //   package foo version 2 using library version Y
498         //   package sharedlibs version 2 exporting library version Y
499         //
500         // Updated packages (installed on /data/apex/active):
501         //   package bar version 1 using library version X (deleted)
502         //   package foo version 1 using library version X (deleted)
503         //   package sharedlibs version 1 exporting library version X (deleted)
504         //
505         for (String apex : new String[]{
506                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
507                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
508                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
509                     SharedLibsVersion.X),
510         }) {
511             mPreparer.deleteFile("/system/apex/" + apex);
512         }
513         for (String apex : new String[]{
514                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y),
515                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y),
516                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.TWO,
517                     SharedLibsVersion.Y),
518         }) {
519             mPreparer.pushResourceFile(apex,
520                     "/system/apex/" + apex);
521         }
522 
523         // Check that files in /data are deleted on first boot.
524         assertThat(getDevice().doesFileExist("/data/apex/active/"
525                 + getInstalledApexFileName(ApexName.BAR, ApexVersion.ONE))).isTrue();
526         assertThat(getDevice().doesFileExist("/data/apex/active/"
527                 + getInstalledApexFileName(ApexName.FOO, ApexVersion.ONE))).isTrue();
528         assertThat(getDevice().doesFileExist("/data/apex/active/"
529                 + getInstalledApexFileName(ApexName.SHAREDLIBS, ApexVersion.ONE))).isTrue();
530         mPreparer.reboot();
531         mHostUtils.waitForFileDeleted("/data/apex/active/"
532                 + getInstalledApexFileName(ApexName.BAR, ApexVersion.ONE), Duration.ofMinutes(3));
533         mHostUtils.waitForFileDeleted("/data/apex/active/"
534                 + getInstalledApexFileName(ApexName.FOO, ApexVersion.ONE), Duration.ofMinutes(3));
535         mHostUtils.waitForFileDeleted("/data/apex/active/"
536                 + getInstalledApexFileName(ApexName.SHAREDLIBS, ApexVersion.ONE),
537                 Duration.ofMinutes(3));
538 
539         getDevice().disableAdbRoot();
540         runAsResult = getDevice().executeShellCommand(
541             "/apex/com.android.apex.test.foo/bin/foo_test");
542         assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y");
543         if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) {
544             runAsResult = getDevice().executeShellCommand(
545                 "/apex/com.android.apex.test.bar/bin/bar_test32");
546             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
547         }
548         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
549             runAsResult = getDevice().executeShellCommand(
550                 "/apex/com.android.apex.test.bar/bin/bar_test64");
551             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
552         }
553     }
554 }
555