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