1 /*
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 
17 package android.os.cts;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.common.truth.Truth.assertWithMessage;
21 
22 import android.platform.test.annotations.AppModeFull;
23 import android.platform.test.annotations.AppModeInstant;
24 import android.platform.test.annotations.LargeTest;
25 import android.platform.test.annotations.Presubmit;
26 
27 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
28 import com.android.compatibility.common.util.PollingCheck;
29 import com.android.ddmlib.Log;
30 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
31 import com.android.ddmlib.testrunner.TestResult.TestStatus;
32 import com.android.tradefed.build.IBuildInfo;
33 import com.android.tradefed.device.DeviceNotAvailableException;
34 import com.android.tradefed.log.LogUtil;
35 import com.android.tradefed.result.CollectingTestListener;
36 import com.android.tradefed.result.TestDescription;
37 import com.android.tradefed.result.TestResult;
38 import com.android.tradefed.result.TestRunResult;
39 import com.android.tradefed.testtype.DeviceTestCase;
40 import com.android.tradefed.testtype.IBuildReceiver;
41 import com.android.tradefed.util.CommandResult;
42 import com.android.tradefed.util.CommandStatus;
43 import com.android.tradefed.util.RunUtil;
44 
45 import java.io.FileNotFoundException;
46 import java.util.Arrays;
47 import java.util.Map;
48 import java.util.concurrent.TimeUnit;
49 import java.util.stream.Collectors;
50 
51 @Presubmit
52 public class StaticSharedLibsHostTests extends DeviceTestCase implements IBuildReceiver {
53     private static final String ANDROID_JUNIT_RUNNER_CLASS =
54             "androidx.test.runner.AndroidJUnitRunner";
55 
56     private static final String STATIC_LIB_PROVIDER_RECURSIVE_APK =
57             "CtsStaticSharedLibProviderRecursive.apk";
58     private static final String STATIC_LIB_PROVIDER_RECURSIVE_PKG =
59             "android.os.lib.provider.recursive";
60 
61     private static final String STATIC_LIB_PROVIDER_RECURSIVE_NAME = "foo.bar.lib.recursive";
62     private static final String STATIC_LIB_PROVIDER_NAME = "foo.bar.lib";
63 
64     private static final String STATIC_LIB_PROVIDER1_APK = "CtsStaticSharedLibProviderApp1.apk";
65     private static final String STATIC_LIB_PROVIDER1_PKG = "android.os.lib.provider";
66 
67     private static final String STATIC_LIB_PROVIDER2_APK = "CtsStaticSharedLibProviderApp2.apk";
68     private static final String STATIC_LIB_PROVIDER2_PKG = "android.os.lib.provider";
69 
70     private static final String STATIC_LIB_PROVIDER3_APK = "CtsStaticSharedLibProviderApp3.apk";
71     private static final String STATIC_LIB_PROVIDER3_PKG = "android.os.lib.provider";
72 
73     private static final String STATIC_LIB_PROVIDER4_APK = "CtsStaticSharedLibProviderApp4.apk";
74     private static final String STATIC_LIB_PROVIDER4_PKG = "android.os.lib.provider";
75 
76     private static final String STATIC_LIB_PROVIDER5_APK = "CtsStaticSharedLibProviderApp5.apk";
77     private static final String STATIC_LIB_PROVIDER5_PKG = "android.os.lib.provider";
78 
79     private static final String STATIC_LIB_PROVIDER6_APK = "CtsStaticSharedLibProviderApp6.apk";
80     private static final String STATIC_LIB_PROVIDER6_PKG = "android.os.lib.provider";
81 
82     private static final String STATIC_LIB_PROVIDER7_APK = "CtsStaticSharedLibProviderApp7.apk";
83     private static final String STATIC_LIB_PROVIDER7_PKG = "android.os.lib.provider";
84 
85     private static final String STATIC_LIB_NATIVE_PROVIDER_APK =
86             "CtsStaticSharedNativeLibProvider.apk";
87     private static final String STATIC_LIB_NATIVE_PROVIDER_PKG =
88             "android.os.lib.provider";
89 
90     private static final String STATIC_LIB_NATIVE_PROVIDER_APK1 =
91             "CtsStaticSharedNativeLibProvider1.apk";
92     private static final String STATIC_LIB_NATIVE_PROVIDER_PKG1 =
93             "android.os.lib.provider";
94 
95     private static final String STATIC_LIB_CONSUMER1_APK = "CtsStaticSharedLibConsumerApp1.apk";
96     private static final String STATIC_LIB_CONSUMER1_BAD_CERT_DIGEST_APK =
97             "CtsStaticSharedLibConsumerApp1BadCertDigest.apk";
98     private static final String STATIC_LIB_CONSUMER1_PKG = "android.os.lib.consumer1";
99 
100     private static final String STATIC_LIB_CONSUMER2_APK = "CtsStaticSharedLibConsumerApp2.apk";
101     private static final String STATIC_LIB_CONSUMER2_PKG = "android.os.lib.consumer2";
102 
103     private static final String STATIC_LIB_CONSUMER3_APK = "CtsStaticSharedLibConsumerApp3.apk";
104     private static final String STATIC_LIB_CONSUMER3_PKG = "android.os.lib.consumer3";
105 
106     private static final String STATIC_LIB_NATIVE_CONSUMER_APK
107             = "CtsStaticSharedNativeLibConsumer.apk";
108     private static final String STATIC_LIB_NATIVE_CONSUMER_PKG
109             = "android.os.lib.consumer";
110 
111     private static final String STATIC_LIB_TEST_APP_PKG = "android.os.lib.app";
112     private static final String STATIC_LIB_TEST_APP_CLASS_NAME = STATIC_LIB_TEST_APP_PKG
113             + ".StaticSharedLibsTests";
114     private static final String STATIC_LIB_MULTI_USER_TEST_APP_CLASS_NAME = STATIC_LIB_TEST_APP_PKG
115             + ".StaticSharedLibsMultiUserTests";
116 
117     private static final String SETTING_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
118             "unused_static_shared_lib_min_cache_period";
119 
120     private static final long DEFAULT_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(15);
121 
122     private CompatibilityBuildHelper mBuildHelper;
123     private boolean mInstantMode = false;
124 
cleanUp()125     private void cleanUp() throws Exception {
126         getDevice().uninstallPackage(STATIC_LIB_CONSUMER3_PKG);
127         getDevice().uninstallPackage(STATIC_LIB_CONSUMER2_PKG);
128         getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
129         getDevice().uninstallPackage(STATIC_LIB_NATIVE_CONSUMER_PKG);
130         getDevice().uninstallPackage(STATIC_LIB_PROVIDER7_PKG);
131         getDevice().uninstallPackage(STATIC_LIB_PROVIDER6_PKG);
132         getDevice().uninstallPackage(STATIC_LIB_PROVIDER5_PKG);
133         getDevice().uninstallPackage(STATIC_LIB_PROVIDER4_PKG);
134         getDevice().uninstallPackage(STATIC_LIB_PROVIDER3_PKG);
135         getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
136         getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
137         getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
138     }
139 
140     @Override
setUp()141     protected void setUp() throws Exception {
142         cleanUp();
143     }
144 
145     @Override
setBuild(IBuildInfo buildInfo)146     public void setBuild(IBuildInfo buildInfo) {
147         mBuildHelper = new CompatibilityBuildHelper(buildInfo);
148     }
149 
150     @AppModeInstant
testInstallSharedLibraryInstantMode()151     public void testInstallSharedLibraryInstantMode() throws Exception {
152         mInstantMode = true;
153         doTestInstallSharedLibrary();
154     }
155 
156     @AppModeFull
testInstallSharedLibraryFullMode()157     public void testInstallSharedLibraryFullMode() throws Exception {
158         doTestInstallSharedLibrary();
159     }
160 
doTestInstallSharedLibrary()161     private void doTestInstallSharedLibrary() throws Exception {
162         try {
163             // Install library dependency
164             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
165             // Install version 1
166             assertNull(install(STATIC_LIB_PROVIDER1_APK));
167             // Install version 2
168             assertNull(install(STATIC_LIB_PROVIDER2_APK));
169             // Uninstall version 1
170             assertNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG));
171             // Uninstall version 2
172             assertNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG));
173             // Uninstall dependency
174             assertNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG));
175         } finally {
176             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
177             getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
178             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
179         }
180     }
181 
182     @AppModeInstant
testCannotInstallSharedLibraryWithMissingDependencyInstantMode()183     public void testCannotInstallSharedLibraryWithMissingDependencyInstantMode() throws Exception {
184         mInstantMode = true;
185         doTestCannotInstallSharedLibraryWithMissingDependency();
186     }
187 
188     @AppModeFull
testCannotInstallSharedLibraryWithMissingDependencyFullMode()189     public void testCannotInstallSharedLibraryWithMissingDependencyFullMode() throws Exception {
190         doTestCannotInstallSharedLibraryWithMissingDependency();
191     }
192 
doTestCannotInstallSharedLibraryWithMissingDependency()193     private void doTestCannotInstallSharedLibraryWithMissingDependency() throws Exception {
194         try {
195             // Install version 1 - should fail - no dependency
196             assertNotNull(install(STATIC_LIB_PROVIDER1_APK));
197         } finally {
198             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
199             getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
200         }
201     }
202 
testLoadCodeAndResourcesFromSharedLibraryRecursively()203     public void testLoadCodeAndResourcesFromSharedLibraryRecursively() throws Exception {
204         try {
205             // Install library dependency
206             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
207             // Install the library
208             assertNull(install(STATIC_LIB_PROVIDER1_APK));
209             // Install the client
210             assertNull(install(STATIC_LIB_CONSUMER1_APK));
211             // Try to load code and resources
212             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
213                     "android.os.lib.consumer1.UseSharedLibraryTest",
214                     "testLoadCodeAndResources");
215         } finally {
216             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
217             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
218             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
219         }
220     }
221 
testLoadCodeAndResourcesFromSharedLibraryRecursivelyUpdate()222     public void testLoadCodeAndResourcesFromSharedLibraryRecursivelyUpdate() throws Exception {
223         try {
224             // Install library dependency
225             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
226             // Install the library
227             assertNull(install(STATIC_LIB_PROVIDER1_APK));
228             // Install the client
229             assertNull(install(STATIC_LIB_CONSUMER1_APK));
230             // Try to load code and resources
231             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
232                     "android.os.lib.consumer1.UseSharedLibraryTest",
233                     "testLoadCodeAndResources");
234             // Install library dependency
235             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK, true));
236             // Try to load code and resources
237             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
238                     "android.os.lib.consumer1.UseSharedLibraryTest",
239                     "testLoadCodeAndResources");
240             // Install the library
241             assertNull(install(STATIC_LIB_PROVIDER1_APK, true));
242             // Try to load code and resources
243             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
244                     "android.os.lib.consumer1.UseSharedLibraryTest",
245                     "testLoadCodeAndResources");
246         } finally {
247             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
248             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
249             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
250         }
251     }
252 
253     @AppModeInstant
testCannotUninstallUsedSharedLibrary1InstantMode()254     public void testCannotUninstallUsedSharedLibrary1InstantMode() throws Exception {
255         mInstantMode = true;
256         doTestCannotUninstallUsedSharedLibrary1();
257     }
258 
259     @AppModeFull
testCannotUninstallUsedSharedLibrary1FullMode()260     public void testCannotUninstallUsedSharedLibrary1FullMode() throws Exception {
261         doTestCannotUninstallUsedSharedLibrary1();
262     }
263 
doTestCannotUninstallUsedSharedLibrary1()264     private void doTestCannotUninstallUsedSharedLibrary1() throws Exception {
265         try {
266             // Install library dependency
267             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
268             // Install the library
269             assertNull(install(STATIC_LIB_PROVIDER1_APK));
270             // The library dependency cannot be uninstalled
271             assertNotNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG));
272             // Now the library dependency can be uninstalled
273             assertNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG));
274             // Uninstall dependency
275             assertNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG));
276         } finally {
277             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
278             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
279         }
280     }
281 
282     @AppModeInstant
testCannotUninstallUsedSharedLibrary2InstantMode()283     public void testCannotUninstallUsedSharedLibrary2InstantMode() throws Exception {
284         mInstantMode = true;
285         doTestCannotUninstallUsedSharedLibrary2();
286     }
287 
288     @AppModeFull
testCannotUninstallUsedSharedLibrary2FullMode()289     public void testCannotUninstallUsedSharedLibrary2FullMode() throws Exception {
290         doTestCannotUninstallUsedSharedLibrary2();
291     }
292 
doTestCannotUninstallUsedSharedLibrary2()293     private void doTestCannotUninstallUsedSharedLibrary2() throws Exception {
294         try {
295             // Install library dependency
296             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
297             // Install the library
298             assertNull(install(STATIC_LIB_PROVIDER1_APK));
299             // Install the client
300             assertNull(install(STATIC_LIB_CONSUMER1_APK));
301             // The library cannot be uninstalled
302             assertNotNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG));
303             // Uninstall the client
304             assertNull(getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG));
305             // Now the library can be uninstalled
306             assertNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG));
307             // Uninstall dependency
308             assertNull(getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG));
309         } finally {
310             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
311             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
312             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
313         }
314     }
315 
316     @AppModeInstant
testLibraryVersionsAndVersionCodesSameOrderInstantMode()317     public void testLibraryVersionsAndVersionCodesSameOrderInstantMode() throws Exception {
318         mInstantMode = true;
319         doTestLibraryVersionsAndVersionCodesSameOrder();
320     }
321 
322     @AppModeFull
testLibraryVersionsAndVersionCodesSameOrderFullMode()323     public void testLibraryVersionsAndVersionCodesSameOrderFullMode() throws Exception {
324         doTestLibraryVersionsAndVersionCodesSameOrder();
325     }
326 
doTestLibraryVersionsAndVersionCodesSameOrder()327     private void doTestLibraryVersionsAndVersionCodesSameOrder() throws Exception {
328         try {
329             // Install library dependency
330             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
331             // Install library version 1 with version code 1
332             assertNull(install(STATIC_LIB_PROVIDER1_APK));
333             // Install library version 2 with version code 4
334             assertNull(install(STATIC_LIB_PROVIDER2_APK));
335             // Shouldn't be able to install library version 3 with version code 3
336             assertNotNull(install(STATIC_LIB_PROVIDER3_APK));
337         } finally {
338             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
339             getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
340             getDevice().uninstallPackage(STATIC_LIB_PROVIDER3_PKG);
341             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
342         }
343     }
344 
345     @AppModeInstant
testCannotInstallAppWithMissingLibraryInstantMode()346     public void testCannotInstallAppWithMissingLibraryInstantMode() throws Exception {
347         mInstantMode = true;
348         doTestCannotInstallAppWithMissingLibrary();
349     }
350 
351     @AppModeFull
testCannotInstallAppWithMissingLibraryFullMode()352     public void testCannotInstallAppWithMissingLibraryFullMode() throws Exception {
353         doTestCannotInstallAppWithMissingLibrary();
354     }
355 
doTestCannotInstallAppWithMissingLibrary()356     private void doTestCannotInstallAppWithMissingLibrary() throws Exception {
357         try {
358             // Shouldn't be able to install an app if a dependency lib is missing
359             assertNotNull(install(STATIC_LIB_CONSUMER1_APK));
360         } finally {
361             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
362         }
363     }
364 
365     @AppModeFull
testCanReplaceLibraryIfVersionAndVersionCodeSame()366     public void testCanReplaceLibraryIfVersionAndVersionCodeSame() throws Exception {
367         try {
368             // Install library dependency
369             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
370             // Install a library
371             assertNull(install(STATIC_LIB_PROVIDER1_APK));
372             // Can reinstall the library if version and version code same
373             assertNull(install(STATIC_LIB_PROVIDER1_APK));
374         } finally {
375             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
376             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
377         }
378     }
379 
380     @AppModeInstant
testUninstallSpecificLibraryVersionInstantMode()381     public void testUninstallSpecificLibraryVersionInstantMode() throws Exception {
382         mInstantMode = true;
383         doTestUninstallSpecificLibraryVersion();
384     }
385 
386     @AppModeFull
testUninstallSpecificLibraryVersionFullMode()387     public void testUninstallSpecificLibraryVersionFullMode() throws Exception {
388         doTestUninstallSpecificLibraryVersion();
389     }
390 
doTestUninstallSpecificLibraryVersion()391     private void doTestUninstallSpecificLibraryVersion() throws Exception {
392         try {
393             // Install library dependency
394             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
395             // Install library version 1 with version code 1
396             assertNull(install(STATIC_LIB_PROVIDER1_APK));
397             // Install library version 2 with version code 4
398             assertNull(install(STATIC_LIB_PROVIDER2_APK));
399             // Uninstall the library package with version code 4 (version 2)
400             assertTrue(getDevice().executeShellCommand("pm uninstall --versionCode 4 "
401                     + STATIC_LIB_PROVIDER1_PKG).startsWith("Success"));
402             // Uninstall the library package with version code 1 (version 1)
403             assertTrue(getDevice().executeShellCommand("pm uninstall "
404                     + STATIC_LIB_PROVIDER1_PKG).startsWith("Success"));
405         } finally {
406             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
407             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
408         }
409     }
410 
411     @AppModeInstant
testKeyRotationInstantMode()412     public void testKeyRotationInstantMode() throws Exception {
413         mInstantMode = true;
414         doTestKeyRotation();
415     }
416 
417     @AppModeFull
testKeyRotationFullMode()418     public void testKeyRotationFullMode() throws Exception {
419         doTestKeyRotation();
420     }
421 
doTestKeyRotation()422     private void doTestKeyRotation() throws Exception {
423         try {
424             // Install a library version specifying an upgrade key set
425             assertNull(install(STATIC_LIB_PROVIDER2_APK));
426             // Install a newer library signed with the upgrade key set
427             assertNull(install(STATIC_LIB_PROVIDER4_APK));
428             // Install a client that depends on the upgraded key set
429             assertNull(install(STATIC_LIB_CONSUMER2_APK));
430             // Ensure code and resources can be loaded
431             runDeviceTests(STATIC_LIB_CONSUMER2_PKG,
432                     "android.os.lib.consumer2.UseSharedLibraryTest",
433                     "testLoadCodeAndResources");
434         } finally {
435             getDevice().uninstallPackage(STATIC_LIB_CONSUMER2_PKG);
436             getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
437             getDevice().uninstallPackage(STATIC_LIB_PROVIDER4_PKG);
438         }
439     }
440 
441     @AppModeInstant
testCannotInstallIncorrectlySignedLibraryInstantMode()442     public void testCannotInstallIncorrectlySignedLibraryInstantMode() throws Exception {
443         mInstantMode = true;
444         doTestCannotInstallIncorrectlySignedLibrary();
445     }
446 
447     @AppModeFull
testCannotInstallIncorrectlySignedLibraryFullMode()448     public void testCannotInstallIncorrectlySignedLibraryFullMode() throws Exception {
449         doTestCannotInstallIncorrectlySignedLibrary();
450     }
451 
doTestCannotInstallIncorrectlySignedLibrary()452     private void doTestCannotInstallIncorrectlySignedLibrary() throws Exception {
453         try {
454             // Install library dependency
455             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
456             // Install a library version not specifying an upgrade key set
457             assertNull(install(STATIC_LIB_PROVIDER1_APK));
458             // Shouldn't be able to install a newer version signed differently
459             assertNotNull(install(STATIC_LIB_PROVIDER4_APK));
460         } finally {
461             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
462             getDevice().uninstallPackage(STATIC_LIB_PROVIDER4_PKG);
463             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
464         }
465     }
466 
467     @AppModeInstant
testLibraryAndPackageNameCanMatchInstantMode()468     public void testLibraryAndPackageNameCanMatchInstantMode() throws Exception {
469         mInstantMode = true;
470         doTestLibraryAndPackageNameCanMatch();
471     }
472 
473     @AppModeFull
testLibraryAndPackageNameCanMatchFullMode()474     public void testLibraryAndPackageNameCanMatchFullMode() throws Exception {
475         doTestLibraryAndPackageNameCanMatch();
476     }
477 
doTestLibraryAndPackageNameCanMatch()478     private void doTestLibraryAndPackageNameCanMatch() throws Exception {
479         try {
480             // Install a library with same name as package should work.
481             assertNull(install(STATIC_LIB_PROVIDER5_APK));
482             // Install a library with same name as package should work.
483             assertNull(install(STATIC_LIB_PROVIDER6_APK));
484         } finally {
485             getDevice().uninstallPackage(STATIC_LIB_PROVIDER5_PKG);
486             getDevice().uninstallPackage(STATIC_LIB_PROVIDER6_PKG);
487         }
488     }
489 
490     @AppModeInstant
testGetSharedLibrariesInstantMode()491     public void testGetSharedLibrariesInstantMode() throws Exception {
492         mInstantMode = true;
493         doTestGetSharedLibraries();
494     }
495 
496     @AppModeFull
testGetSharedLibrariesFullMode()497     public void testGetSharedLibrariesFullMode() throws Exception {
498         doTestGetSharedLibraries();
499     }
500 
doTestGetSharedLibraries()501     private void doTestGetSharedLibraries() throws Exception {
502         try {
503             // Install library dependency
504             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
505             // Install the first library
506             assertNull(install(STATIC_LIB_PROVIDER1_APK));
507             // Install the second library
508             assertNull(install(STATIC_LIB_PROVIDER2_APK));
509             // Install the third library
510             assertNull(install(STATIC_LIB_PROVIDER4_APK));
511             // Install the first client
512             assertNull(install(STATIC_LIB_CONSUMER1_APK));
513             // Install the second client
514             assertNull(install(STATIC_LIB_CONSUMER2_APK));
515             // Ensure the first library has the REQUEST_INSTALL_PACKAGES app op
516             getDevice().executeShellV2Command("appops set "
517                     + STATIC_LIB_CONSUMER1_PKG
518                     + " REQUEST_INSTALL_PACKAGES allow");
519             // Ensure libraries are properly reported
520             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
521                     "android.os.lib.consumer1.UseSharedLibraryTest",
522                     "testSharedLibrariesProperlyReported");
523         } finally {
524             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
525             getDevice().uninstallPackage(STATIC_LIB_CONSUMER2_PKG);
526             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
527             getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
528             getDevice().uninstallPackage(STATIC_LIB_PROVIDER4_PKG);
529             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
530         }
531     }
532 
533     @AppModeFull(
534             reason = "getDeclaredSharedLibraries() requires ACCESS_SHARED_LIBRARIES permission")
testGetDeclaredSharedLibraries()535     public void testGetDeclaredSharedLibraries() throws Exception {
536         try {
537             // Install library dependency
538             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
539             // Install the first library
540             assertNull(install(STATIC_LIB_PROVIDER1_APK));
541             // Install the second library
542             assertNull(install(STATIC_LIB_PROVIDER2_APK));
543             // Install the third library
544             assertNull(install(STATIC_LIB_PROVIDER4_APK));
545             // Install the first client
546             assertNull(install(STATIC_LIB_CONSUMER1_APK));
547             // Install the second client
548             assertNull(install(STATIC_LIB_CONSUMER2_APK));
549             // Ensure declared libraries are properly reported
550             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
551                     "android.os.lib.consumer1.UseSharedLibraryTest",
552                     "testDeclaredSharedLibrariesProperlyReported");
553         } finally {
554             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
555             getDevice().uninstallPackage(STATIC_LIB_CONSUMER2_PKG);
556             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
557             getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
558             getDevice().uninstallPackage(STATIC_LIB_PROVIDER4_PKG);
559             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
560         }
561     }
562 
563     @AppModeInstant
testAppCanSeeOnlyLibrariesItDependOnInstantMode()564     public void testAppCanSeeOnlyLibrariesItDependOnInstantMode() throws Exception {
565         mInstantMode = true;
566         doTestAppCanSeeOnlyLibrariesItDependOn();
567     }
568 
569     @AppModeFull
testAppCanSeeOnlyLibrariesItDependOnFullMode()570     public void testAppCanSeeOnlyLibrariesItDependOnFullMode() throws Exception {
571         doTestAppCanSeeOnlyLibrariesItDependOn();
572     }
573 
doTestAppCanSeeOnlyLibrariesItDependOn()574     private void doTestAppCanSeeOnlyLibrariesItDependOn() throws Exception {
575         try {
576             // Install library dependency
577             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
578             // Install the first library
579             assertNull(install(STATIC_LIB_PROVIDER1_APK));
580             // Install the second library
581             assertNull(install(STATIC_LIB_PROVIDER2_APK));
582             // Install the client
583             assertNull(install(STATIC_LIB_CONSUMER1_APK));
584             // Ensure the client can see only the lib it depends on
585             runDeviceTests(STATIC_LIB_CONSUMER1_PKG,
586                     "android.os.lib.consumer1.UseSharedLibraryTest",
587                     "testAppCanSeeOnlyLibrariesItDependOn");
588         } finally {
589             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
590             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
591             getDevice().uninstallPackage(STATIC_LIB_PROVIDER2_PKG);
592             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
593         }
594     }
595 
596     @AppModeInstant
testLoadCodeFromNativeLibInstantMode()597     public void testLoadCodeFromNativeLibInstantMode() throws Exception {
598         mInstantMode = true;
599         doTestLoadCodeFromNativeLib();
600     }
601 
602     @AppModeFull
testLoadCodeFromNativeLibFullMode()603     public void testLoadCodeFromNativeLibFullMode() throws Exception {
604         doTestLoadCodeFromNativeLib();
605     }
606 
doTestLoadCodeFromNativeLib()607     private void doTestLoadCodeFromNativeLib() throws Exception {
608         try {
609             // Install library
610             assertNull(install(STATIC_LIB_NATIVE_PROVIDER_APK));
611             // Install the library client
612             assertNull(install(STATIC_LIB_NATIVE_CONSUMER_APK));
613             // Ensure the client can load native code from the library
614             runDeviceTests(STATIC_LIB_NATIVE_CONSUMER_PKG,
615                     "android.os.lib.consumer.UseSharedLibraryTest",
616                     "testLoadNativeCode");
617         } finally {
618             getDevice().uninstallPackage(STATIC_LIB_NATIVE_CONSUMER_PKG);
619             getDevice().uninstallPackage(STATIC_LIB_NATIVE_PROVIDER_PKG);
620         }
621     }
622 
623     @AppModeInstant
testLoadCodeFromNativeLibMultiArchViolationInstantMode()624     public void testLoadCodeFromNativeLibMultiArchViolationInstantMode() throws Exception {
625         mInstantMode = true;
626         doTestLoadCodeFromNativeLibMultiArchViolation();
627     }
628 
629     @AppModeFull
testLoadCodeFromNativeLibMultiArchViolationFullMode()630     public void testLoadCodeFromNativeLibMultiArchViolationFullMode() throws Exception {
631         doTestLoadCodeFromNativeLibMultiArchViolation();
632     }
633 
doTestLoadCodeFromNativeLibMultiArchViolation()634     private void doTestLoadCodeFromNativeLibMultiArchViolation() throws Exception {
635         try {
636             // Cannot install the library with native code if not multi-arch
637             assertNotNull(install(STATIC_LIB_NATIVE_PROVIDER_APK1));
638         } finally {
639             getDevice().uninstallPackage(STATIC_LIB_NATIVE_PROVIDER_PKG1);
640         }
641     }
642 
643     @AppModeInstant
testLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCertsInstantMode()644     public void testLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCertsInstantMode() throws Exception {
645         mInstantMode = true;
646         doTestLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCerts();
647     }
648 
649     @AppModeFull
testLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCertsFullMode()650     public void testLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCertsFullMode() throws Exception {
651         doTestLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCerts();
652     }
653 
doTestLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCerts()654     private void doTestLoadCodeAndResourcesFromSharedLibrarySignedWithTwoCerts()
655             throws Exception {
656         try {
657             // Install the library
658             assertNull(install(STATIC_LIB_PROVIDER7_APK));
659             // Install the client
660             assertNull(install(STATIC_LIB_CONSUMER3_APK));
661             // Try to load code and resources
662             runDeviceTests(STATIC_LIB_CONSUMER3_PKG,
663                     "android.os.lib.consumer3.UseSharedLibraryTest",
664                     "testLoadCodeAndResources");
665         } finally {
666             getDevice().uninstallPackage(STATIC_LIB_CONSUMER3_PKG);
667             getDevice().uninstallPackage(STATIC_LIB_PROVIDER7_PKG);
668         }
669     }
670 
testSamegradeStaticSharedLibByAdb()671     public void testSamegradeStaticSharedLibByAdb() throws Exception {
672         try {
673             assertNull(install(STATIC_LIB_PROVIDER5_APK));
674             assertNull(install(STATIC_LIB_PROVIDER5_APK, true /*reinstall*/));
675         } finally {
676             getDevice().uninstallPackage(STATIC_LIB_PROVIDER5_PKG);
677         }
678     }
679 
680     @AppModeFull(reason = "Instant app cannot get package installer service")
testCannotSamegradeStaticSharedLibByInstaller()681     public void testCannotSamegradeStaticSharedLibByInstaller() throws Exception {
682         runDeviceTests(STATIC_LIB_TEST_APP_PKG, STATIC_LIB_TEST_APP_CLASS_NAME,
683                 "testSamegradeStaticSharedLibFail");
684     }
685 
runDeviceTests(String packageName, String testClassName, String testMethodName)686     private void runDeviceTests(String packageName, String testClassName,
687             String testMethodName) throws DeviceNotAvailableException {
688         RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName,
689                 ANDROID_JUNIT_RUNNER_CLASS, getDevice().getIDevice());
690         testRunner.setMethodName(testClassName, testMethodName);
691         CollectingTestListener listener = new CollectingTestListener();
692 
693         getDevice().runInstrumentationTests(testRunner, listener);
694 
695         final TestRunResult result = listener.getCurrentRunResults();
696         if (result.isRunFailure()) {
697             throw new AssertionError("Failed to successfully run device tests for "
698                     + result.getName() + ": " + result.getRunFailureMessage());
699         }
700         if (result.getNumTests() == 0) {
701             throw new AssertionError("No tests were run on the device");
702         }
703         if (result.hasFailedTests()) {
704             // build a meaningful error message
705             StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
706             for (Map.Entry<TestDescription, TestResult> resultEntry :
707                     result.getTestResults().entrySet()) {
708                 if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
709                     errorBuilder.append(resultEntry.getKey().toString());
710                     errorBuilder.append(":\n");
711                     errorBuilder.append(resultEntry.getValue().getStackTrace());
712                 }
713             }
714             throw new AssertionError(errorBuilder.toString());
715         }
716     }
717 
718     @LargeTest
719     @AppModeFull
testPruneUnusedStaticSharedLibrariesWithMultiUser_reboot_fullMode()720     public void testPruneUnusedStaticSharedLibrariesWithMultiUser_reboot_fullMode()
721             throws Exception {
722         // This really should be a assumeTrue(getDevice().getMaxNumberOfUsersSupported() > 1), but
723         // JUnit3 doesn't support assumptions framework.
724         // TODO: change to assumeTrue after migrating tests to JUnit4.
725         final int maxUserCount = getDevice().getMaxNumberOfUsersSupported();
726         if (!(maxUserCount > 1)) {
727             LogUtil.CLog.logAndDisplay(Log.LogLevel.INFO, "The device does not support multi-user");
728             return;
729         }
730 
731         boolean shouldCreateSecondUser = true;
732         // Check whether the current user count on the device is not less than the max user count or
733         // not. If yes, don't create the other user.
734         final int currentUserCount = getDevice().listUsers().size();
735         if (currentUserCount >= maxUserCount) {
736             String message = String.format("Current user count %s is not less than the max user"
737                     + " count %s, don't create the other user.", currentUserCount, maxUserCount);
738             LogUtil.CLog.logAndDisplay(Log.LogLevel.INFO, message);
739             shouldCreateSecondUser = false;
740         }
741 
742 
743         doTestPruneUnusedStaticSharedLibrariesWithMultiUser_reboot(shouldCreateSecondUser);
744     }
745 
746     @LargeTest
747     @AppModeInstant
testPruneUnusedStaticSharedLibrariesWithMultiUser_reboot_instantMode()748     public void testPruneUnusedStaticSharedLibrariesWithMultiUser_reboot_instantMode()
749             throws Exception {
750         // This really should be a assumeTrue(getDevice().getMaxNumberOfUsersSupported() > 1), but
751         // JUnit3 doesn't support assumptions framework.
752         // TODO: change to assumeTrue after migrating tests to JUnit4.
753         final int maxUserCount = getDevice().getMaxNumberOfUsersSupported();
754         if (!(maxUserCount > 1)) {
755             LogUtil.CLog.logAndDisplay(Log.LogLevel.INFO, "The device does not support multi-user");
756             return;
757         }
758 
759         boolean shouldCreateSecondUser = true;
760         // Check whether the current user count on the device is not less than the max user count or
761         // not. If yes, don't create the other user.
762         final int currentUserCount = getDevice().listUsers().size();
763         if (currentUserCount >= maxUserCount) {
764             String message = String.format("Current user count %s is not less than the max user"
765                     + " count %s, don't create the other user.", currentUserCount, maxUserCount);
766             LogUtil.CLog.logAndDisplay(Log.LogLevel.INFO, message);
767             shouldCreateSecondUser = false;
768         }
769 
770         mInstantMode = true;
771         doTestPruneUnusedStaticSharedLibrariesWithMultiUser_reboot(shouldCreateSecondUser);
772     }
773 
doTestPruneUnusedStaticSharedLibrariesWithMultiUser_reboot( boolean shouldCreateSecondUser)774     private void doTestPruneUnusedStaticSharedLibrariesWithMultiUser_reboot(
775             boolean shouldCreateSecondUser) throws Exception {
776         int userId = -1;
777         try {
778             if (shouldCreateSecondUser) {
779                 userId = createAndStartSecondUser();
780                 assertThat(userId).isNotEqualTo(-1);
781             }
782             doTestPruneUnusedStaticSharedLibraries_reboot();
783         } finally {
784             if (shouldCreateSecondUser) {
785                 stopAndRemoveUser(userId);
786             }
787         }
788     }
789 
790     @LargeTest
791     @AppModeFull
testPruneUnusedStaticSharedLibraries_reboot_fullMode()792     public void testPruneUnusedStaticSharedLibraries_reboot_fullMode()
793             throws Exception {
794         doTestPruneUnusedStaticSharedLibraries_reboot();
795     }
796 
797     @LargeTest
798     @AppModeInstant
testPruneUnusedStaticSharedLibraries_reboot_instantMode()799     public void testPruneUnusedStaticSharedLibraries_reboot_instantMode()
800             throws Exception {
801         mInstantMode = true;
802         doTestPruneUnusedStaticSharedLibraries_reboot();
803     }
804 
doTestPruneUnusedStaticSharedLibraries_reboot()805     private void doTestPruneUnusedStaticSharedLibraries_reboot()
806             throws Exception {
807         try {
808             // Install an unused library
809             assertThat(install(STATIC_LIB_PROVIDER_RECURSIVE_APK)).isNull();
810             assertThat(checkLibrary(STATIC_LIB_PROVIDER_RECURSIVE_NAME)).isTrue();
811 
812             // Install the client and the corresponding library
813             assertThat(install(STATIC_LIB_PROVIDER7_APK)).isNull();
814             assertThat(install(STATIC_LIB_CONSUMER3_APK)).isNull();
815             assertThat(checkLibrary(STATIC_LIB_PROVIDER_NAME)).isTrue();
816 
817             // Disallow to cache static shared library
818             setGlobalSetting(SETTING_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
819                     Integer.toString(0));
820 
821             // TODO(205779832): There's a maximum two-seconds-delay before SettingsProvider persists
822             //  the settings. Waits for 3 seconds before reboot the device to ensure the setting is
823             //  persisted.
824             RunUtil.getDefault().sleep(3_000);
825             getDevice().reboot();
826 
827             // Waits for the uninstallation of the unused library to ensure the job has be executed
828             // correctly.
829             PollingCheck.check("Library " + STATIC_LIB_PROVIDER_RECURSIVE_NAME
830                             + " should be uninstalled", DEFAULT_TIMEOUT_MILLIS,
831                     () -> !checkLibrary(STATIC_LIB_PROVIDER_RECURSIVE_NAME));
832             assertWithMessage(
833                     "Library " + STATIC_LIB_PROVIDER_NAME + " should not be uninstalled")
834                     .that(checkLibrary(STATIC_LIB_PROVIDER_NAME)).isTrue();
835         } finally {
836             setGlobalSetting(SETTING_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD, null);
837             getDevice().uninstallPackage(STATIC_LIB_CONSUMER3_PKG);
838             getDevice().uninstallPackage(STATIC_LIB_PROVIDER7_PKG);
839             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
840         }
841     }
842 
843     @LargeTest
844     @AppModeFull
testInstallStaticSharedLib_notKillDependentApp()845     public void testInstallStaticSharedLib_notKillDependentApp() throws Exception {
846         try {
847             // Install library dependency
848             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
849             // Install the first library
850             assertNull(install(STATIC_LIB_PROVIDER1_APK));
851             // Install the client
852             assertNull(install(STATIC_LIB_CONSUMER1_APK));
853 
854             // Bind the service in consumer1 app to verify that the app should not be killed when
855             // a new version static shared library installed.
856             runDeviceTests(STATIC_LIB_TEST_APP_PKG, STATIC_LIB_TEST_APP_CLASS_NAME,
857                     "testInstallStaticSharedLib_notKillDependentApp");
858         } finally {
859             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
860             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
861             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
862         }
863     }
864 
865     @AppModeFull
testSamegradeStaticSharedLib_killDependentApp()866     public void testSamegradeStaticSharedLib_killDependentApp() throws Exception {
867         try {
868             // Install library dependency
869             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
870             // Install the first library
871             assertNull(install(STATIC_LIB_PROVIDER1_APK));
872             // Install the client
873             assertNull(install(STATIC_LIB_CONSUMER1_APK));
874 
875             // Bind the service in consumer1 app to verify that the app should be killed when
876             // the static shared library is re-installed.
877             runDeviceTests(STATIC_LIB_TEST_APP_PKG, STATIC_LIB_TEST_APP_CLASS_NAME,
878                     "testSamegradeStaticSharedLib_killDependentApp");
879         } finally {
880             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
881             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
882             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
883         }
884     }
885 
886     @AppModeFull
testStaticSharedLibInstall_broadcastReceived()887     public void testStaticSharedLibInstall_broadcastReceived() throws Exception {
888         // Install library dependency
889         assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
890         runDeviceTests(STATIC_LIB_TEST_APP_PKG, STATIC_LIB_TEST_APP_CLASS_NAME,
891                     "testStaticSharedLibInstall_broadcastReceived");
892     }
893 
894     @AppModeFull
testStaticSharedLibInstall_incorrectInstallerPkgName_broadcastNotReceived()895     public void testStaticSharedLibInstall_incorrectInstallerPkgName_broadcastNotReceived()
896             throws Exception {
897         // Install library dependency
898         assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
899         runDeviceTests(STATIC_LIB_TEST_APP_PKG, STATIC_LIB_TEST_APP_CLASS_NAME,
900                 "testStaticSharedLibInstall_incorrectInstallerPkgName_broadcastNotReceived");
901     }
902 
903     @AppModeFull
testStaticSharedLibUninstall_broadcastReceived()904     public void testStaticSharedLibUninstall_broadcastReceived()
905             throws Exception {
906         // Install library dependency
907         assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
908         runDeviceTests(STATIC_LIB_TEST_APP_PKG, STATIC_LIB_TEST_APP_CLASS_NAME,
909                 "testStaticSharedLibUninstall_broadcastReceived");
910     }
911 
912     @AppModeFull
testStaticSharedLibUninstall_incorrectInstallerPkgName_broadcastNotReceived()913     public void testStaticSharedLibUninstall_incorrectInstallerPkgName_broadcastNotReceived()
914             throws Exception {
915         // Install library dependency
916         assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
917         runDeviceTests(STATIC_LIB_TEST_APP_PKG, STATIC_LIB_TEST_APP_CLASS_NAME,
918                 "testStaticSharedLibUninstall_incorrectInstallerPkgName_broadcastNotReceived");
919     }
920 
921     @AppModeFull
testStaticSharedLibInstallOnSecondaryUser_broadcastReceivedByAllUsers()922     public void testStaticSharedLibInstallOnSecondaryUser_broadcastReceivedByAllUsers()
923             throws Exception {
924 
925         runDeviceTests(STATIC_LIB_TEST_APP_PKG, STATIC_LIB_MULTI_USER_TEST_APP_CLASS_NAME,
926                 "testStaticSharedLibInstallOnSecondaryUser_broadcastReceivedByAllUsers");
927     }
928 
929     @AppModeFull
testStaticSharedLibUninstallOnAllUsers_broadcastReceivedByAllUsers()930     public void testStaticSharedLibUninstallOnAllUsers_broadcastReceivedByAllUsers()
931             throws Exception {
932 
933         runDeviceTests(STATIC_LIB_TEST_APP_PKG, STATIC_LIB_MULTI_USER_TEST_APP_CLASS_NAME,
934                 "testStaticSharedLibUninstallOnAllUsers_broadcastReceivedByAllUsers");
935     }
936 
937     @AppModeFull
testCannotInstallAppWithBadCertDigestDeclared()938     public void testCannotInstallAppWithBadCertDigestDeclared() throws Exception {
939         try {
940             // Install library dependency
941             assertNull(install(STATIC_LIB_PROVIDER_RECURSIVE_APK));
942             // Install the first library
943             assertNull(install(STATIC_LIB_PROVIDER1_APK));
944             // Failed to install app with bad certificate digest
945             assertThat(install(STATIC_LIB_CONSUMER1_BAD_CERT_DIGEST_APK))
946                     .contains("INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST");
947         } finally {
948             getDevice().uninstallPackage(STATIC_LIB_CONSUMER1_PKG);
949             getDevice().uninstallPackage(STATIC_LIB_PROVIDER1_PKG);
950             getDevice().uninstallPackage(STATIC_LIB_PROVIDER_RECURSIVE_PKG);
951         }
952     }
953 
install(String apk)954     private String install(String apk) throws DeviceNotAvailableException, FileNotFoundException {
955         return install(apk, false);
956     }
install(String apk, boolean reinstall)957     private String install(String apk, boolean reinstall)
958             throws DeviceNotAvailableException, FileNotFoundException {
959         return getDevice().installPackage(mBuildHelper.getTestFile(apk), reinstall, false,
960                 apk.contains("consumer") && mInstantMode ? "--instant" : "");
961     }
962 
checkLibrary(String libName)963     private boolean checkLibrary(String libName) throws DeviceNotAvailableException {
964         final CommandResult result = getDevice().executeShellV2Command("pm list libraries");
965         if (result.getStatus() != CommandStatus.SUCCESS) {
966             fail("Failed to execute shell command: pm list libraries");
967         }
968         return Arrays.stream(result.getStdout().split("\n"))
969                 .map(line -> line.split(":")[1])
970                 .collect(Collectors.toList()).contains(libName);
971     }
972 
setGlobalSetting(String key, String value)973     private void setGlobalSetting(String key, String value) throws DeviceNotAvailableException {
974         final boolean deleteKey = (value == null);
975         final StringBuilder cmd = new StringBuilder("settings ");
976         if (deleteKey) {
977             cmd.append("delete ");
978         } else {
979             cmd.append("put ");
980         }
981         cmd.append("global ").append(key);
982         if (!deleteKey) {
983             cmd.append(" ").append(value);
984         }
985         final CommandResult res = getDevice().executeShellV2Command(cmd.toString());
986         if (res.getStatus() != CommandStatus.SUCCESS) {
987             fail("Failed to execute shell command: " + cmd);
988         }
989     }
990 
createAndStartSecondUser()991     private int createAndStartSecondUser() throws Exception {
992         String output = getDevice().executeShellCommand("pm create-user SecondUser");
993         assertThat(output.startsWith("Success")).isTrue();
994         int userId = Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
995         output = getDevice().executeShellCommand("am start-user -w " + userId);
996         assertThat(output.startsWith("Error")).isFalse();
997         output = getDevice().executeShellCommand("am get-started-user-state " + userId);
998         assertThat(output.contains("RUNNING_UNLOCKED")).isTrue();
999         return userId;
1000     }
1001 
stopAndRemoveUser(int userId)1002     private void stopAndRemoveUser(int userId) throws Exception {
1003         getDevice().executeShellCommand("am stop-user -w -f " + userId);
1004         getDevice().executeShellCommand("pm remove-user " + userId);
1005     }
1006 }
1007