• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.content.pm;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertNull;
22 import static org.junit.Assert.assertTrue;
23 
24 import android.apex.ApexInfo;
25 import android.content.Context;
26 import android.content.pm.PackageParser.Component;
27 import android.content.pm.PackageParser.Package;
28 import android.content.pm.PackageParser.Permission;
29 import android.os.Build;
30 import android.os.Bundle;
31 import android.os.FileUtils;
32 import android.os.SystemProperties;
33 
34 import androidx.test.InstrumentationRegistry;
35 import androidx.test.filters.SmallTest;
36 import androidx.test.runner.AndroidJUnit4;
37 
38 import com.android.frameworks.coretests.R;
39 
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 
43 import java.io.File;
44 import java.io.InputStream;
45 import java.util.Arrays;
46 import java.util.function.Function;
47 
48 @SmallTest
49 @RunWith(AndroidJUnit4.class)
50 public class PackageParserTest {
51     private static final String RELEASED = null;
52     private static final String OLDER_PRE_RELEASE = "A";
53     private static final String PRE_RELEASE = "B";
54     private static final String NEWER_PRE_RELEASE = "C";
55 
56     // Codenames with a fingerprint attached to them. These may only be present in the apps
57     // declared min SDK and not as platform codenames.
58     private static final String OLDER_PRE_RELEASE_WITH_FINGERPRINT = "A.fingerprint";
59     private static final String PRE_RELEASE_WITH_FINGERPRINT = "B.fingerprint";
60     private static final String NEWER_PRE_RELEASE_WITH_FINGERPRINT = "C.fingerprint";
61 
62     private static final String[] CODENAMES_RELEASED = { /* empty */ };
63     private static final String[] CODENAMES_PRE_RELEASE = { PRE_RELEASE };
64 
65     private static final int OLDER_VERSION = 10;
66     private static final int PLATFORM_VERSION = 20;
67     private static final int NEWER_VERSION = 30;
68 
verifyComputeMinSdkVersion(int minSdkVersion, String minSdkCodename, boolean isPlatformReleased, int expectedMinSdk)69     private void verifyComputeMinSdkVersion(int minSdkVersion, String minSdkCodename,
70             boolean isPlatformReleased, int expectedMinSdk) {
71         final String[] outError = new String[1];
72         final int result = PackageParser.computeMinSdkVersion(
73                 minSdkVersion,
74                 minSdkCodename,
75                 PLATFORM_VERSION,
76                 isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
77                 outError);
78 
79         assertEquals("Error msg: " + outError[0], expectedMinSdk, result);
80 
81         if (expectedMinSdk == -1) {
82             assertNotNull(outError[0]);
83         } else {
84             assertNull(outError[0]);
85         }
86     }
87 
88     @Test
testComputeMinSdkVersion_preReleasePlatform()89     public void testComputeMinSdkVersion_preReleasePlatform() {
90         // Do allow older release minSdkVersion on pre-release platform.
91         // APP: Released API 10
92         // DEV: Pre-release API 20
93         verifyComputeMinSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION);
94 
95         // Do allow same release minSdkVersion on pre-release platform.
96         // APP: Released API 20
97         // DEV: Pre-release API 20
98         verifyComputeMinSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION);
99 
100         // Don't allow newer release minSdkVersion on pre-release platform.
101         // APP: Released API 30
102         // DEV: Pre-release API 20
103         verifyComputeMinSdkVersion(NEWER_VERSION, RELEASED, false, -1);
104 
105         // Don't allow older pre-release minSdkVersion on pre-release platform.
106         // APP: Pre-release API 10
107         // DEV: Pre-release API 20
108         verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1);
109         verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);
110 
111         // Do allow same pre-release minSdkVersion on pre-release platform,
112         // but overwrite the specified version with CUR_DEVELOPMENT.
113         // APP: Pre-release API 20
114         // DEV: Pre-release API 20
115         verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false,
116                 Build.VERSION_CODES.CUR_DEVELOPMENT);
117         verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, false,
118                 Build.VERSION_CODES.CUR_DEVELOPMENT);
119 
120 
121         // Don't allow newer pre-release minSdkVersion on pre-release platform.
122         // APP: Pre-release API 30
123         // DEV: Pre-release API 20
124         verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1);
125         verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);
126     }
127 
128     @Test
testComputeMinSdkVersion_releasedPlatform()129     public void testComputeMinSdkVersion_releasedPlatform() {
130         // Do allow older release minSdkVersion on released platform.
131         // APP: Released API 10
132         // DEV: Released API 20
133         verifyComputeMinSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION);
134 
135         // Do allow same release minSdkVersion on released platform.
136         // APP: Released API 20
137         // DEV: Released API 20
138         verifyComputeMinSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION);
139 
140         // Don't allow newer release minSdkVersion on released platform.
141         // APP: Released API 30
142         // DEV: Released API 20
143         verifyComputeMinSdkVersion(NEWER_VERSION, RELEASED, true, -1);
144 
145         // Don't allow older pre-release minSdkVersion on released platform.
146         // APP: Pre-release API 10
147         // DEV: Released API 20
148         verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1);
149         verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);
150 
151         // Don't allow same pre-release minSdkVersion on released platform.
152         // APP: Pre-release API 20
153         // DEV: Released API 20
154         verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1);
155         verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, true, -1);
156 
157 
158         // Don't allow newer pre-release minSdkVersion on released platform.
159         // APP: Pre-release API 30
160         // DEV: Released API 20
161         verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1);
162         verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);
163     }
164 
verifyComputeTargetSdkVersion(int targetSdkVersion, String targetSdkCodename, boolean isPlatformReleased, int expectedTargetSdk)165     private void verifyComputeTargetSdkVersion(int targetSdkVersion, String targetSdkCodename,
166             boolean isPlatformReleased, int expectedTargetSdk) {
167         final String[] outError = new String[1];
168         final int result = PackageParser.computeTargetSdkVersion(
169                 targetSdkVersion,
170                 targetSdkCodename,
171                 isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
172                 outError);
173 
174         assertEquals(result, expectedTargetSdk);
175 
176         if (expectedTargetSdk == -1) {
177             assertNotNull(outError[0]);
178         } else {
179             assertNull(outError[0]);
180         }
181     }
182 
183     @Test
testComputeTargetSdkVersion_preReleasePlatform()184     public void testComputeTargetSdkVersion_preReleasePlatform() {
185         // Do allow older release targetSdkVersion on pre-release platform.
186         // APP: Released API 10
187         // DEV: Pre-release API 20
188         verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION);
189 
190         // Do allow same release targetSdkVersion on pre-release platform.
191         // APP: Released API 20
192         // DEV: Pre-release API 20
193         verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION);
194 
195         // Do allow newer release targetSdkVersion on pre-release platform.
196         // APP: Released API 30
197         // DEV: Pre-release API 20
198         verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, false, NEWER_VERSION);
199 
200         // Don't allow older pre-release targetSdkVersion on pre-release platform.
201         // APP: Pre-release API 10
202         // DEV: Pre-release API 20
203         verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1);
204         verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);
205 
206 
207         // Do allow same pre-release targetSdkVersion on pre-release platform,
208         // but overwrite the specified version with CUR_DEVELOPMENT.
209         // APP: Pre-release API 20
210         // DEV: Pre-release API 20
211         verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false,
212                 Build.VERSION_CODES.CUR_DEVELOPMENT);
213         verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, false,
214                 Build.VERSION_CODES.CUR_DEVELOPMENT);
215 
216 
217         // Don't allow newer pre-release targetSdkVersion on pre-release platform.
218         // APP: Pre-release API 30
219         // DEV: Pre-release API 20
220         verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1);
221         verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);
222     }
223 
224     @Test
testComputeTargetSdkVersion_releasedPlatform()225     public void testComputeTargetSdkVersion_releasedPlatform() {
226         // Do allow older release targetSdkVersion on released platform.
227         // APP: Released API 10
228         // DEV: Released API 20
229         verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION);
230 
231         // Do allow same release targetSdkVersion on released platform.
232         // APP: Released API 20
233         // DEV: Released API 20
234         verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION);
235 
236         // Do allow newer release targetSdkVersion on released platform.
237         // APP: Released API 30
238         // DEV: Released API 20
239         verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, true, NEWER_VERSION);
240 
241         // Don't allow older pre-release targetSdkVersion on released platform.
242         // APP: Pre-release API 10
243         // DEV: Released API 20
244         verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1);
245         verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);
246 
247         // Don't allow same pre-release targetSdkVersion on released platform.
248         // APP: Pre-release API 20
249         // DEV: Released API 20
250         verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1);
251         verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, true, -1);
252 
253 
254         // Don't allow newer pre-release targetSdkVersion on released platform.
255         // APP: Pre-release API 30
256         // DEV: Released API 20
257         verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1);
258         verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);
259     }
260 
261     /**
262      * Unit test for PackageParser.getActivityConfigChanges().
263      * If the bit is 1 in the original configChanges, it is still 1 in the final configChanges.
264      * If the bit is 0 in the original configChanges and the bit is not set to 1 in
265      * recreateOnConfigChanges, the bit is changed to 1 in the final configChanges by default.
266      */
267     @Test
testGetActivityConfigChanges()268     public void testGetActivityConfigChanges() {
269         // Not set in either configChanges or recreateOnConfigChanges.
270         int configChanges = 0x0000; // 00000000.
271         int recreateOnConfigChanges = 0x0000; // 00000000.
272         int finalConfigChanges =
273                 PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
274         assertEquals(0x0003, finalConfigChanges); // Should be 00000011.
275 
276         // Not set in configChanges, but set in recreateOnConfigChanges.
277         configChanges = 0x0000; // 00000000.
278         recreateOnConfigChanges = 0x0003; // 00000011.
279         finalConfigChanges =
280                 PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
281         assertEquals(0x0000, finalConfigChanges); // Should be 00000000.
282 
283         // Set in configChanges.
284         configChanges = 0x0003; // 00000011.
285         recreateOnConfigChanges = 0X0000; // 00000000.
286         finalConfigChanges =
287                 PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
288         assertEquals(0x0003, finalConfigChanges); // Should be 00000011.
289 
290         recreateOnConfigChanges = 0x0003; // 00000011.
291         finalConfigChanges =
292                 PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
293         assertEquals(0x0003, finalConfigChanges); // Should still be 00000011.
294 
295         // Other bit set in configChanges.
296         configChanges = 0x0080; // 10000000, orientation.
297         recreateOnConfigChanges = 0x0000; // 00000000.
298         finalConfigChanges =
299                 PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
300         assertEquals(0x0083, finalConfigChanges); // Should be 10000011.
301     }
302 
parsePackage(String apkFileName, int apkResourceId)303     Package parsePackage(String apkFileName, int apkResourceId) throws Exception {
304         return parsePackage(apkFileName, apkResourceId, p -> p);
305     }
306 
307     /**
308      * Copies a specified {@code resourceId} to a file. Returns a non-null file if the copy
309      * succeeded, or {@code null} otherwise.
310      */
copyRawResourceToFile(String baseName, int resourceId)311     File copyRawResourceToFile(String baseName, int resourceId) throws Exception {
312         // Copy the resource to a file.
313         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
314         InputStream is = context.getResources().openRawResource(resourceId);
315         File outFile = null;
316         try {
317             outFile = new File(context.getFilesDir(), baseName);
318             assertTrue(FileUtils.copyToFile(is, outFile));
319             return outFile;
320         } catch (Exception e) {
321             if (outFile != null) {
322                 outFile.delete();
323             }
324 
325             return null;
326         }
327     }
328 
329     /**
330      * Attempts to parse a package.
331      *
332      * APKs are put into coretests/apks/packageparser_*.
333      *
334      * @param apkFileName temporary file name to store apk extracted from resources
335      * @param apkResourceId identifier of the apk as a resource
336      */
parsePackage(String apkFileName, int apkResourceId, Function<Package, Package> converter)337     Package parsePackage(String apkFileName, int apkResourceId,
338             Function<Package, Package> converter) throws Exception {
339         // Copy the resource to a file.
340         File outFile = null;
341         try {
342             outFile = copyRawResourceToFile(apkFileName, apkResourceId);
343             return converter.apply(new PackageParser().parsePackage(outFile, 0 /* flags */));
344         } finally {
345             if (outFile != null) {
346                 outFile.delete();
347             }
348         }
349     }
350 
351     /**
352      * Asserts basic properties about a component.
353      */
assertComponent(String className, String packageName, int numIntents, Component<?> component)354     private void assertComponent(String className, String packageName, int numIntents,
355             Component<?> component) {
356         assertEquals(className, component.className);
357         assertEquals(packageName, component.owner.packageName);
358         assertEquals(numIntents, component.intents.size());
359     }
360 
361     /**
362      * Asserts four regularly-named components of each type: one Activity, one Service, one
363      * Provider, and one Receiver.
364      * @param template templated string with %s subbed with Activity, Service, Provider, Receiver
365      */
assertOneComponentOfEachType(String template, Package p)366     private void assertOneComponentOfEachType(String template, Package p) {
367         String packageName = p.packageName;
368 
369         assertEquals(1, p.activities.size());
370         assertComponent(String.format(template, "Activity"),
371                 packageName, 0 /* intents */, p.activities.get(0));
372         assertEquals(1, p.services.size());
373         assertComponent(String.format(template, "Service"),
374                 packageName, 0 /* intents */, p.services.get(0));
375         assertEquals(1, p.providers.size());
376         assertComponent(String.format(template, "Provider"),
377                 packageName, 0 /* intents */, p.providers.get(0));
378         assertEquals(1, p.receivers.size());
379         assertComponent(String.format(template, "Receiver"),
380                 packageName, 0 /* intents */, p.receivers.get(0));
381     }
382 
assertPermission(String name, String packageName, int protectionLevel, Permission permission)383     private void assertPermission(String name, String packageName, int protectionLevel,
384             Permission permission) {
385         assertEquals(packageName, permission.owner.packageName);
386         assertEquals(name, permission.info.name);
387         assertEquals(protectionLevel, permission.info.protectionLevel);
388     }
389 
assertMetadata(Bundle b, String... keysAndValues)390     private void assertMetadata(Bundle b, String... keysAndValues) {
391         assertTrue("Odd number of elements in keysAndValues", (keysAndValues.length % 2) == 0);
392 
393         assertNotNull(b);
394         assertEquals(keysAndValues.length / 2, b.size());
395 
396         for (int i = 0; i < keysAndValues.length; i += 2) {
397             final String key = keysAndValues[i];
398             final String value = keysAndValues[i + 1];
399 
400             assertEquals(value, b.getString(key));
401         }
402     }
403 
404     // TODO Add a "_cached" test for testMultiPackageComponents() too, after fixing b/64295061.
405     // Package.writeToParcel can't handle circular package references.
406 
407     @Test
testPackageWithComponents_no_cache()408     public void testPackageWithComponents_no_cache() throws Exception {
409         checkPackageWithComponents(p -> p);
410     }
411 
412     @Test
testPackageWithComponents_cached()413     public void testPackageWithComponents_cached() throws Exception {
414         checkPackageWithComponents(p ->
415                 PackageParser.fromCacheEntryStatic(PackageParser.toCacheEntryStatic(p)));
416     }
417 
checkPackageWithComponents( Function<Package, Package> converter)418     private void checkPackageWithComponents(
419             Function<Package, Package> converter) throws Exception {
420         Package p = parsePackage(
421                 "install_complete_package_info.apk", R.raw.install_complete_package_info,
422                 converter);
423         String packageName = "com.android.frameworks.coretests.install_complete_package_info";
424 
425         assertEquals(packageName, p.packageName);
426         assertEquals(1, p.permissions.size());
427         assertPermission(
428                 "com.android.frameworks.coretests.install_complete_package_info.test_permission",
429                 packageName, PermissionInfo.PROTECTION_NORMAL, p.permissions.get(0));
430 
431         assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", p);
432 
433         assertMetadata(p.mAppMetaData,
434                 "key1", "value1",
435                 "key2", "this_is_app");
436         assertMetadata(p.activities.get(0).metaData,
437                 "key1", "value1",
438                 "key2", "this_is_activity");
439         assertMetadata(p.services.get(0).metaData,
440                 "key1", "value1",
441                 "key2", "this_is_service");
442         assertMetadata(p.receivers.get(0).metaData,
443                 "key1", "value1",
444                 "key2", "this_is_receiver");
445         assertMetadata(p.providers.get(0).metaData,
446                 "key1", "value1",
447                 "key2", "this_is_provider");
448     }
449 
450     /**
451      * Determines if the current device supports multi-package APKs.
452      */
supportsMultiPackageApk()453     private boolean supportsMultiPackageApk() {
454         return SystemProperties.getBoolean("persist.sys.child_packages_enabled", false);
455     }
456 
457     @Test
testMultiPackageComponents()458     public void testMultiPackageComponents() throws Exception {
459         // TODO(gboyer): Remove once we decide to launch multi-package APKs.
460         if (!supportsMultiPackageApk()) {
461             return;
462         }
463         String parentName = "com.android.frameworks.coretests.install_multi_package";
464         String firstChildName =
465                 "com.android.frameworks.coretests.install_multi_package.first_child";
466         String secondChildName =  // NOTE: intentionally inconsistent!
467                 "com.android.frameworks.coretests.blah.second_child";
468 
469         Package parent = parsePackage("install_multi_package.apk", R.raw.install_multi_package);
470         assertEquals(parentName, parent.packageName);
471         assertEquals(2, parent.childPackages.size());
472         assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", parent);
473         assertEquals(1, parent.permissions.size());
474         assertPermission(parentName + ".test_permission", parentName,
475                 PermissionInfo.PROTECTION_NORMAL, parent.permissions.get(0));
476         assertEquals(Arrays.asList("android.permission.INTERNET"),
477                 parent.requestedPermissions);
478 
479         Package firstChild = parent.childPackages.get(0);
480         assertEquals(firstChildName, firstChild.packageName);
481         assertOneComponentOfEachType(
482                 "com.android.frameworks.coretests.FirstChildTest%s", firstChild);
483         assertEquals(0, firstChild.permissions.size());  // Child APKs cannot declare permissions.
484         assertEquals(Arrays.asList("android.permission.NFC"),
485                 firstChild.requestedPermissions);
486 
487         Package secondChild = parent.childPackages.get(1);
488         assertEquals(secondChildName, secondChild.packageName);
489         assertOneComponentOfEachType(
490                 "com.android.frameworks.coretests.SecondChildTest%s", secondChild);
491         assertEquals(0, secondChild.permissions.size());  // Child APKs cannot declare permissions.
492         assertEquals(
493                 Arrays.asList(
494                         "android.permission.ACCESS_NETWORK_STATE",
495                         "android.permission.READ_CONTACTS"),
496                 secondChild.requestedPermissions);
497     }
498 
499     @Test
testApexPackageInfoGeneration()500     public void testApexPackageInfoGeneration() throws Exception {
501         String apexPackageName = "com.android.tzdata.apex";
502         File apexFile = copyRawResourceToFile(apexPackageName,
503                 R.raw.com_android_tzdata);
504         ApexInfo apexInfo = new ApexInfo();
505         apexInfo.isActive = true;
506         apexInfo.isFactory = false;
507         apexInfo.packageName = apexPackageName;
508         apexInfo.packagePath = apexFile.getPath();
509         apexInfo.versionCode = 191000070;
510         int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES;
511         PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexInfo, flags);
512         assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
513         assertTrue(pi.applicationInfo.enabled);
514         assertEquals(28, pi.applicationInfo.targetSdkVersion);
515         assertEquals(191000070, pi.applicationInfo.longVersionCode);
516         assertNotNull(pi.applicationInfo.metaData);
517         assertEquals(apexFile.getPath(), pi.applicationInfo.sourceDir);
518         assertEquals("Bundle[{com.android.vending.derived.apk.id=1}]",
519                 pi.applicationInfo.metaData.toString());
520 
521         assertEquals("com.google.android.tzdata", pi.packageName);
522         assertEquals(191000070, pi.getLongVersionCode());
523         assertNotNull(pi.signingInfo);
524         assertTrue(pi.signingInfo.getApkContentsSigners().length > 0);
525         assertTrue(pi.isApex);
526         assertTrue((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0);
527         assertTrue((pi.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0);
528     }
529 }
530