PackageParserTest.java revision be0b8896d1bc385d4c8fb54c21929745935dcbea
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 */
16package com.android.server.pm;
17
18import android.annotation.TestApi;
19import android.content.pm.ActivityInfo;
20import android.content.pm.ApplicationInfo;
21import android.content.pm.ConfigurationInfo;
22import android.content.pm.FeatureGroupInfo;
23import android.content.pm.FeatureInfo;
24import android.content.pm.InstrumentationInfo;
25import android.content.pm.PackageParser;
26import android.content.pm.ProviderInfo;
27import android.content.pm.ServiceInfo;
28import android.content.pm.Signature;
29import android.os.Bundle;
30import android.os.Parcel;
31import android.support.test.runner.AndroidJUnit4;
32import android.test.suitebuilder.annotation.MediumTest;
33
34import java.io.File;
35import java.lang.reflect.Array;
36import java.lang.reflect.Field;
37import java.nio.charset.StandardCharsets;
38import java.security.cert.Certificate;
39import java.util.ArrayList;
40import java.util.Arrays;
41import java.util.HashSet;
42import java.util.List;
43import java.util.Set;
44
45import static org.junit.Assert.*;
46
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import org.junit.Before;
50import org.junit.Test;
51import org.junit.runner.RunWith;
52
53import libcore.io.IoUtils;
54
55@RunWith(AndroidJUnit4.class)
56@MediumTest
57public class PackageParserTest {
58    private File mTmpDir;
59    private static final File FRAMEWORK = new File("/system/framework/framework-res.apk");
60
61    @Before
62    public void setUp() {
63        // Create a new temporary directory for each of our tests.
64        mTmpDir = IoUtils.createTemporaryDirectory("PackageParserTest");
65    }
66
67    @Test
68    public void testParse_noCache() throws Exception {
69        PackageParser pp = new CachePackageNameParser();
70        PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
71                false /* useCaches */);
72        assertNotNull(pkg);
73
74        pp.setCacheDir(mTmpDir);
75        pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
76                false /* useCaches */);
77        assertNotNull(pkg);
78
79        // Make sure that we always write out a cache entry for future reference,
80        // whether or not we're asked to use caches.
81        assertEquals(1, mTmpDir.list().length);
82    }
83
84    @Test
85    public void testParse_withCache() throws Exception {
86        PackageParser pp = new CachePackageNameParser();
87
88        pp.setCacheDir(mTmpDir);
89        // The first parse will write this package to the cache.
90        pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);
91
92        // Now attempt to parse the package again, should return the
93        // cached result.
94        PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
95                true /* useCaches */);
96        assertEquals("cache_android", pkg.packageName);
97
98        // Try again, with useCaches == false, shouldn't return the parsed
99        // result.
100        pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */);
101        assertEquals("android", pkg.packageName);
102
103        // We haven't set a cache directory here : the parse should still succeed,
104        // just not using the cached results.
105        pp = new CachePackageNameParser();
106        pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);
107        assertEquals("android", pkg.packageName);
108
109        pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */);
110        assertEquals("android", pkg.packageName);
111    }
112
113    @Test
114    public void test_serializePackage() throws Exception {
115        PackageParser pp = new PackageParser();
116        pp.setCacheDir(mTmpDir);
117
118        PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
119            true /* useCaches */);
120
121        Parcel p = Parcel.obtain();
122        pkg.writeToParcel(p, 0 /* flags */);
123
124        p.setDataPosition(0);
125        PackageParser.Package deserialized = new PackageParser.Package(p);
126
127        assertPackagesEqual(pkg, deserialized);
128    }
129
130    @Test
131    public void test_roundTripKnownFields() throws Exception {
132        PackageParser.Package pkg = new PackageParser.Package("foo");
133        setKnownFields(pkg);
134
135        Parcel p = Parcel.obtain();
136        pkg.writeToParcel(p, 0 /* flags */);
137
138        p.setDataPosition(0);
139        PackageParser.Package deserialized = new PackageParser.Package(p);
140        assertAllFieldsExist(deserialized);
141    }
142
143    /**
144     * A trivial subclass of package parser that only caches the package name, and throws away
145     * all other information.
146     */
147    public static class CachePackageNameParser extends PackageParser {
148        @Override
149        public byte[] toCacheEntry(Package pkg) {
150            return ("cache_" + pkg.packageName).getBytes(StandardCharsets.UTF_8);
151        }
152
153        @Override
154        public Package fromCacheEntry(byte[] cacheEntry) {
155            return new Package(new String(cacheEntry, StandardCharsets.UTF_8));
156        }
157    }
158
159    // NOTE: The equality assertions below are based on code autogenerated by IntelliJ.
160
161    public static void assertPackagesEqual(PackageParser.Package a, PackageParser.Package b) {
162        assertEquals(a.baseRevisionCode, b.baseRevisionCode);
163        assertEquals(a.baseHardwareAccelerated, b.baseHardwareAccelerated);
164        assertEquals(a.mVersionCode, b.mVersionCode);
165        assertEquals(a.mSharedUserLabel, b.mSharedUserLabel);
166        assertEquals(a.mPreferredOrder, b.mPreferredOrder);
167        assertEquals(a.installLocation, b.installLocation);
168        assertEquals(a.coreApp, b.coreApp);
169        assertEquals(a.mRequiredForAllUsers, b.mRequiredForAllUsers);
170        assertEquals(a.mOverlayPriority, b.mOverlayPriority);
171        assertEquals(a.mTrustedOverlay, b.mTrustedOverlay);
172        assertEquals(a.use32bitAbi, b.use32bitAbi);
173        assertEquals(a.packageName, b.packageName);
174        assertTrue(Arrays.equals(a.splitNames, b.splitNames));
175        assertEquals(a.volumeUuid, b.volumeUuid);
176        assertEquals(a.codePath, b.codePath);
177        assertEquals(a.baseCodePath, b.baseCodePath);
178        assertTrue(Arrays.equals(a.splitCodePaths, b.splitCodePaths));
179        assertTrue(Arrays.equals(a.splitRevisionCodes, b.splitRevisionCodes));
180        assertTrue(Arrays.equals(a.splitFlags, b.splitFlags));
181        assertTrue(Arrays.equals(a.splitPrivateFlags, b.splitPrivateFlags));
182        assertApplicationInfoEqual(a.applicationInfo, b.applicationInfo);
183
184        assertEquals(a.permissions.size(), b.permissions.size());
185        for (int i = 0; i < a.permissions.size(); ++i) {
186            assertPermissionsEqual(a.permissions.get(i), b.permissions.get(i));
187            assertSame(a.permissions.get(i).owner, a);
188            assertSame(b.permissions.get(i).owner, b);
189        }
190
191        assertEquals(a.permissionGroups.size(), b.permissionGroups.size());
192        for (int i = 0; i < a.permissionGroups.size(); ++i) {
193            assertPermissionGroupsEqual(a.permissionGroups.get(i), b.permissionGroups.get(i));
194        }
195
196        assertEquals(a.activities.size(), b.activities.size());
197        for (int i = 0; i < a.activities.size(); ++i) {
198            assertActivitiesEqual(a.activities.get(i), b.activities.get(i));
199        }
200
201        assertEquals(a.receivers.size(), b.receivers.size());
202        for (int i = 0; i < a.receivers.size(); ++i) {
203            assertActivitiesEqual(a.receivers.get(i), b.receivers.get(i));
204        }
205
206        assertEquals(a.providers.size(), b.providers.size());
207        for (int i = 0; i < a.providers.size(); ++i) {
208            assertProvidersEqual(a.providers.get(i), b.providers.get(i));
209        }
210
211        assertEquals(a.services.size(), b.services.size());
212        for (int i = 0; i < a.services.size(); ++i) {
213            assertServicesEqual(a.services.get(i), b.services.get(i));
214        }
215
216        assertEquals(a.instrumentation.size(), b.instrumentation.size());
217        for (int i = 0; i < a.instrumentation.size(); ++i) {
218            assertInstrumentationEqual(a.instrumentation.get(i), b.instrumentation.get(i));
219        }
220
221        assertEquals(a.requestedPermissions, b.requestedPermissions);
222        assertEquals(a.protectedBroadcasts, b.protectedBroadcasts);
223        assertEquals(a.parentPackage, b.parentPackage);
224        assertEquals(a.childPackages, b.childPackages);
225        assertEquals(a.libraryNames, b.libraryNames);
226        assertEquals(a.usesLibraries, b.usesLibraries);
227        assertEquals(a.usesOptionalLibraries, b.usesOptionalLibraries);
228        assertTrue(Arrays.equals(a.usesLibraryFiles, b.usesLibraryFiles));
229        assertEquals(a.mOriginalPackages, b.mOriginalPackages);
230        assertEquals(a.mRealPackage, b.mRealPackage);
231        assertEquals(a.mAdoptPermissions, b.mAdoptPermissions);
232        assertBundleApproximateEquals(a.mAppMetaData, b.mAppMetaData);
233        assertEquals(a.mVersionName, b.mVersionName);
234        assertEquals(a.mSharedUserId, b.mSharedUserId);
235        assertTrue(Arrays.equals(a.mSignatures, b.mSignatures));
236        assertTrue(Arrays.equals(a.mCertificates, b.mCertificates));
237        assertTrue(Arrays.equals(a.mLastPackageUsageTimeInMills, b.mLastPackageUsageTimeInMills));
238        assertEquals(a.mExtras, b.mExtras);
239        assertEquals(a.mRestrictedAccountType, b.mRestrictedAccountType);
240        assertEquals(a.mRequiredAccountType, b.mRequiredAccountType);
241        assertEquals(a.mOverlayTarget, b.mOverlayTarget);
242        assertEquals(a.mSigningKeys, b.mSigningKeys);
243        assertEquals(a.mUpgradeKeySets, b.mUpgradeKeySets);
244        assertEquals(a.mKeySetMapping, b.mKeySetMapping);
245        assertEquals(a.cpuAbiOverride, b.cpuAbiOverride);
246        assertTrue(Arrays.equals(a.restrictUpdateHash, b.restrictUpdateHash));
247    }
248
249    private static void assertBundleApproximateEquals(Bundle a, Bundle b) {
250        if (a == b) {
251            return;
252        }
253
254        // Force the bundles to be unparceled.
255        a.getBoolean("foo");
256        b.getBoolean("foo");
257
258        assertEquals(a.toString(), b.toString());
259    }
260
261    private static void assertComponentsEqual(PackageParser.Component<?> a,
262                                              PackageParser.Component<?> b) {
263        assertEquals(a.className, b.className);
264        assertBundleApproximateEquals(a.metaData, b.metaData);
265        assertEquals(a.getComponentName(), b.getComponentName());
266
267        if (a.intents != null && b.intents != null) {
268            assertEquals(a.intents.size(), b.intents.size());
269        } else if (a.intents == null || b.intents == null) {
270            return;
271        }
272
273        for (int i = 0; i < a.intents.size(); ++i) {
274            PackageParser.IntentInfo aIntent = a.intents.get(i);
275            PackageParser.IntentInfo bIntent = b.intents.get(i);
276
277            assertEquals(aIntent.hasDefault, bIntent.hasDefault);
278            assertEquals(aIntent.labelRes, bIntent.labelRes);
279            assertEquals(aIntent.nonLocalizedLabel, bIntent.nonLocalizedLabel);
280            assertEquals(aIntent.icon, bIntent.icon);
281            assertEquals(aIntent.logo, bIntent.logo);
282            assertEquals(aIntent.banner, bIntent.banner);
283            assertEquals(aIntent.preferred, bIntent.preferred);
284        }
285    }
286
287    private static void assertPermissionsEqual(PackageParser.Permission a,
288                                               PackageParser.Permission b) {
289        assertComponentsEqual(a, b);
290        assertEquals(a.tree, b.tree);
291
292        // Verify basic flags in PermissionInfo to make sure they're consistent. We don't perform
293        // a full structural equality here because the code that serializes them isn't parser
294        // specific and is tested elsewhere.
295        assertEquals(a.info.protectionLevel, b.info.protectionLevel);
296        assertEquals(a.info.group, b.info.group);
297        assertEquals(a.info.flags, b.info.flags);
298
299        if (a.group != null && b.group != null) {
300            assertPermissionGroupsEqual(a.group, b.group);
301        } else if (a.group != null || b.group != null) {
302            throw new AssertionError();
303        }
304    }
305
306    private static void assertInstrumentationEqual(PackageParser.Instrumentation a,
307                                                   PackageParser.Instrumentation b) {
308        assertComponentsEqual(a, b);
309
310        // Sanity check for InstrumentationInfo.
311        assertEquals(a.info.targetPackage, b.info.targetPackage);
312        assertEquals(a.info.targetProcess, b.info.targetProcess);
313        assertEquals(a.info.sourceDir, b.info.sourceDir);
314        assertEquals(a.info.publicSourceDir, b.info.publicSourceDir);
315    }
316
317    private static void assertServicesEqual(PackageParser.Service a, PackageParser.Service b) {
318        assertComponentsEqual(a, b);
319
320        // Sanity check for ServiceInfo.
321        assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo);
322        assertEquals(a.info.name, b.info.name);
323    }
324
325    private static void assertProvidersEqual(PackageParser.Provider a, PackageParser.Provider b) {
326        assertComponentsEqual(a, b);
327
328        // Sanity check for ProviderInfo
329        assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo);
330        assertEquals(a.info.name, b.info.name);
331    }
332
333    private static void assertActivitiesEqual(PackageParser.Activity a, PackageParser.Activity b) {
334        assertComponentsEqual(a, b);
335
336        // Sanity check for ActivityInfo.
337        assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo);
338        assertEquals(a.info.name, b.info.name);
339    }
340
341    private static void assertPermissionGroupsEqual(PackageParser.PermissionGroup a,
342                                                    PackageParser.PermissionGroup b) {
343        assertComponentsEqual(a, b);
344
345        // Sanity check for PermissionGroupInfo.
346        assertEquals(a.info.name, b.info.name);
347        assertEquals(a.info.descriptionRes, b.info.descriptionRes);
348    }
349
350    private static void assertApplicationInfoEqual(ApplicationInfo a, ApplicationInfo that) {
351        assertEquals(a.descriptionRes, that.descriptionRes);
352        assertEquals(a.theme, that.theme);
353        assertEquals(a.fullBackupContent, that.fullBackupContent);
354        assertEquals(a.uiOptions, that.uiOptions);
355        assertEquals(a.flags, that.flags);
356        assertEquals(a.privateFlags, that.privateFlags);
357        assertEquals(a.requiresSmallestWidthDp, that.requiresSmallestWidthDp);
358        assertEquals(a.compatibleWidthLimitDp, that.compatibleWidthLimitDp);
359        assertEquals(a.largestWidthLimitDp, that.largestWidthLimitDp);
360        assertEquals(a.nativeLibraryRootRequiresIsa, that.nativeLibraryRootRequiresIsa);
361        assertEquals(a.uid, that.uid);
362        assertEquals(a.minSdkVersion, that.minSdkVersion);
363        assertEquals(a.targetSdkVersion, that.targetSdkVersion);
364        assertEquals(a.versionCode, that.versionCode);
365        assertEquals(a.enabled, that.enabled);
366        assertEquals(a.enabledSetting, that.enabledSetting);
367        assertEquals(a.installLocation, that.installLocation);
368        assertEquals(a.networkSecurityConfigRes, that.networkSecurityConfigRes);
369        assertEquals(a.taskAffinity, that.taskAffinity);
370        assertEquals(a.permission, that.permission);
371        assertEquals(a.processName, that.processName);
372        assertEquals(a.className, that.className);
373        assertEquals(a.manageSpaceActivityName, that.manageSpaceActivityName);
374        assertEquals(a.backupAgentName, that.backupAgentName);
375        assertEquals(a.volumeUuid, that.volumeUuid);
376        assertEquals(a.scanSourceDir, that.scanSourceDir);
377        assertEquals(a.scanPublicSourceDir, that.scanPublicSourceDir);
378        assertEquals(a.sourceDir, that.sourceDir);
379        assertEquals(a.publicSourceDir, that.publicSourceDir);
380        assertTrue(Arrays.equals(a.splitSourceDirs, that.splitSourceDirs));
381        assertTrue(Arrays.equals(a.splitPublicSourceDirs, that.splitPublicSourceDirs));
382        assertTrue(Arrays.equals(a.resourceDirs, that.resourceDirs));
383        assertEquals(a.seInfo, that.seInfo);
384        assertTrue(Arrays.equals(a.sharedLibraryFiles, that.sharedLibraryFiles));
385        assertEquals(a.dataDir, that.dataDir);
386        assertEquals(a.deviceProtectedDataDir, that.deviceProtectedDataDir);
387        assertEquals(a.deviceEncryptedDataDir, that.deviceEncryptedDataDir);
388        assertEquals(a.credentialProtectedDataDir, that.credentialProtectedDataDir);
389        assertEquals(a.credentialEncryptedDataDir, that.credentialEncryptedDataDir);
390        assertEquals(a.nativeLibraryDir, that.nativeLibraryDir);
391        assertEquals(a.secondaryNativeLibraryDir, that.secondaryNativeLibraryDir);
392        assertEquals(a.nativeLibraryRootDir, that.nativeLibraryRootDir);
393        assertEquals(a.primaryCpuAbi, that.primaryCpuAbi);
394        assertEquals(a.secondaryCpuAbi, that.secondaryCpuAbi);
395    }
396
397    public static void setKnownFields(PackageParser.Package pkg) {
398        pkg.baseRevisionCode = 100;
399        pkg.baseHardwareAccelerated = true;
400        pkg.mVersionCode = 100;
401        pkg.mSharedUserLabel = 100;
402        pkg.mPreferredOrder = 100;
403        pkg.installLocation = 100;
404        pkg.coreApp = true;
405        pkg.mRequiredForAllUsers = true;
406        pkg.mOverlayPriority = 100;
407        pkg.mTrustedOverlay = true;
408        pkg.use32bitAbi = true;
409        pkg.packageName = "foo";
410        pkg.splitNames = new String[] { "foo" };
411        pkg.volumeUuid = "foo";
412        pkg.codePath = "foo";
413        pkg.baseCodePath = "foo";
414        pkg.splitCodePaths = new String[] { "foo" };
415        pkg.splitRevisionCodes = new int[] { 100 };
416        pkg.splitFlags = new int[] { 100 };
417        pkg.splitPrivateFlags = new int[] { 100 };
418        pkg.applicationInfo = new ApplicationInfo();
419
420        pkg.permissions.add(new PackageParser.Permission(pkg));
421        pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg));
422
423        final PackageParser.ParseComponentArgs dummy = new PackageParser.ParseComponentArgs(
424                pkg, new String[1], 0, 0, 0, 0, 0, 0, null, 0, 0, 0);
425
426        pkg.activities.add(new PackageParser.Activity(dummy, new ActivityInfo()));
427        pkg.receivers.add(new PackageParser.Activity(dummy, new ActivityInfo()));
428        pkg.providers.add(new PackageParser.Provider(dummy, new ProviderInfo()));
429        pkg.services.add(new PackageParser.Service(dummy, new ServiceInfo()));
430        pkg.instrumentation.add(new PackageParser.Instrumentation(dummy, new InstrumentationInfo()));
431        pkg.requestedPermissions.add("foo");
432
433        pkg.protectedBroadcasts = new ArrayList<>();
434        pkg.protectedBroadcasts.add("foo");
435
436        pkg.parentPackage = new PackageParser.Package("foo");
437
438        pkg.childPackages = new ArrayList<>();
439        pkg.childPackages.add(new PackageParser.Package("bar"));
440
441        pkg.libraryNames = new ArrayList<>();
442        pkg.libraryNames.add("foo");
443
444        pkg.usesLibraries = new ArrayList<>();
445        pkg.usesLibraries.add("foo");
446
447        pkg.usesOptionalLibraries = new ArrayList<>();
448        pkg.usesOptionalLibraries.add("foo");
449
450        pkg.usesLibraryFiles = new String[] { "foo "};
451
452        pkg.mOriginalPackages = new ArrayList<>();
453        pkg.mOriginalPackages.add("foo");
454
455        pkg.mRealPackage = "foo";
456
457        pkg.mAdoptPermissions = new ArrayList<>();
458        pkg.mAdoptPermissions.add("foo");
459
460        pkg.mAppMetaData = new Bundle();
461        pkg.mVersionName = "foo";
462        pkg.mSharedUserId = "foo";
463        pkg.mSignatures = new Signature[] { new Signature(new byte[16]) };
464        pkg.mCertificates = new Certificate[][] { new Certificate[] { null }};
465        pkg.mExtras = new Bundle();
466        pkg.mRestrictedAccountType = "foo";
467        pkg.mRequiredAccountType = "foo";
468        pkg.mOverlayTarget = "foo";
469        pkg.mSigningKeys = new ArraySet<>();
470        pkg.mUpgradeKeySets = new ArraySet<>();
471        pkg.mKeySetMapping = new ArrayMap<>();
472        pkg.cpuAbiOverride = "foo";
473        pkg.restrictUpdateHash = new byte[16];
474
475        pkg.preferredActivityFilters = new ArrayList<>();
476        pkg.preferredActivityFilters.add(new PackageParser.ActivityIntentInfo(
477                new PackageParser.Activity(dummy, new ActivityInfo())));
478
479        pkg.configPreferences = new ArrayList<>();
480        pkg.configPreferences.add(new ConfigurationInfo());
481
482        pkg.reqFeatures = new ArrayList<>();
483        pkg.reqFeatures.add(new FeatureInfo());
484
485        pkg.featureGroups = new ArrayList<>();
486        pkg.featureGroups.add(new FeatureGroupInfo());
487    }
488
489    private static void assertAllFieldsExist(PackageParser.Package pkg) throws Exception {
490        Field[] fields = PackageParser.Package.class.getDeclaredFields();
491
492        Set<String> nonSerializedFields = new HashSet<>();
493        nonSerializedFields.add("mExtras");
494        nonSerializedFields.add("packageUsageTimeMillis");
495
496        for (Field f : fields) {
497            final Class<?> fieldType = f.getType();
498
499            if (nonSerializedFields.contains(f.getName())) {
500                continue;
501            }
502
503            if (List.class.isAssignableFrom(fieldType)) {
504                // Sanity check for list fields: Assume they're non-null and contain precisely
505                // one element.
506                List<?> list = (List<?>) f.get(pkg);
507                assertNotNull(list);
508                assertEquals(1, list.size());
509            } else if (fieldType.getComponentType() != null) {
510                // Sanity check for array fields: Assume they're non-null and contain precisely
511                // one element.
512                Object array = f.get(pkg);
513                assertNotNull(Array.get(array, 0));
514            } else if (fieldType == String.class) {
515                // String fields: Check that they're set to "foo".
516                String value = (String) f.get(pkg);
517                assertEquals("foo", value);
518            } else if (fieldType == int.class) {
519                // int fields: Check that they're set to 100.
520                int value = (int) f.get(pkg);
521                assertEquals(100, value);
522            } else {
523                // All other fields: Check that they're set.
524                Object o = f.get(pkg);
525                assertNotNull("Field was null: " + f.getName(), o);
526            }
527        }
528    }
529}
530
531