/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.pm;

import static android.content.res.Resources.ID_NULL;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.FeatureGroupInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageParser;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.Signature;
import android.os.Bundle;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
import android.util.ArrayMap;
import android.util.ArraySet;

import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import libcore.io.IoUtils;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@RunWith(AndroidJUnit4.class)
@MediumTest
public class PackageParserTest {
    private File mTmpDir;
    private static final File FRAMEWORK = new File("/system/framework/framework-res.apk");

    @Before
    public void setUp() {
        // Create a new temporary directory for each of our tests.
        mTmpDir = IoUtils.createTemporaryDirectory("PackageParserTest");
    }

    @Test
    public void testParse_noCache() throws Exception {
        PackageParser pp = new CachePackageNameParser();
        PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
                false /* useCaches */);
        assertNotNull(pkg);

        pp.setCacheDir(mTmpDir);
        pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
                false /* useCaches */);
        assertNotNull(pkg);

        // Make sure that we always write out a cache entry for future reference,
        // whether or not we're asked to use caches.
        assertEquals(1, mTmpDir.list().length);
    }

    @Test
    public void testParse_withCache() throws Exception {
        PackageParser pp = new CachePackageNameParser();

        pp.setCacheDir(mTmpDir);
        // The first parse will write this package to the cache.
        pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);

        // Now attempt to parse the package again, should return the
        // cached result.
        PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
                true /* useCaches */);
        assertEquals("cache_android", pkg.packageName);

        // Try again, with useCaches == false, shouldn't return the parsed
        // result.
        pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */);
        assertEquals("android", pkg.packageName);

        // We haven't set a cache directory here : the parse should still succeed,
        // just not using the cached results.
        pp = new CachePackageNameParser();
        pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);
        assertEquals("android", pkg.packageName);

        pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */);
        assertEquals("android", pkg.packageName);
    }

    @Test
    public void test_serializePackage() throws Exception {
        PackageParser pp = new PackageParser();
        pp.setCacheDir(mTmpDir);

        PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
            true /* useCaches */);

        Parcel p = Parcel.obtain();
        pkg.writeToParcel(p, 0 /* flags */);

        p.setDataPosition(0);
        PackageParser.Package deserialized = new PackageParser.Package(p);

        assertPackagesEqual(pkg, deserialized);
    }

    @Test
    @SmallTest
    @Presubmit
    public void test_roundTripKnownFields() throws Exception {
        PackageParser.Package pkg = new PackageParser.Package("foo");
        setKnownFields(pkg);

        Parcel p = Parcel.obtain();
        pkg.writeToParcel(p, 0 /* flags */);

        p.setDataPosition(0);
        PackageParser.Package deserialized = new PackageParser.Package(p);
        assertAllFieldsExist(deserialized);
    }

    @Test
    public void test_stringInterning() throws Exception {
        PackageParser.Package pkg = new PackageParser.Package("foo");
        setKnownFields(pkg);

        Parcel p = Parcel.obtain();
        pkg.writeToParcel(p, 0 /* flags */);

        p.setDataPosition(0);
        PackageParser.Package deserialized = new PackageParser.Package(p);

        p.setDataPosition(0);
        PackageParser.Package deserialized2 = new PackageParser.Package(p);

        assertSame(deserialized.packageName, deserialized2.packageName);
        assertSame(deserialized.applicationInfo.permission,
                deserialized2.applicationInfo.permission);
        assertSame(deserialized.requestedPermissions.get(0),
                deserialized2.requestedPermissions.get(0));
        assertSame(deserialized.protectedBroadcasts.get(0),
                deserialized2.protectedBroadcasts.get(0));
        assertSame(deserialized.usesLibraries.get(0),
                deserialized2.usesLibraries.get(0));
        assertSame(deserialized.usesOptionalLibraries.get(0),
                deserialized2.usesOptionalLibraries.get(0));
        assertSame(deserialized.mVersionName, deserialized2.mVersionName);
        assertSame(deserialized.mSharedUserId, deserialized2.mSharedUserId);
    }


    /**
     * A trivial subclass of package parser that only caches the package name, and throws away
     * all other information.
     */
    public static class CachePackageNameParser extends PackageParser {
        @Override
        public byte[] toCacheEntry(Package pkg) {
            return ("cache_" + pkg.packageName).getBytes(StandardCharsets.UTF_8);
        }

        @Override
        public Package fromCacheEntry(byte[] cacheEntry) {
            return new Package(new String(cacheEntry, StandardCharsets.UTF_8));
        }
    }

    // NOTE: The equality assertions below are based on code autogenerated by IntelliJ.

    public static void assertPackagesEqual(PackageParser.Package a, PackageParser.Package b) {
        assertEquals(a.baseRevisionCode, b.baseRevisionCode);
        assertEquals(a.baseHardwareAccelerated, b.baseHardwareAccelerated);
        assertEquals(a.mVersionCode, b.mVersionCode);
        assertEquals(a.mSharedUserLabel, b.mSharedUserLabel);
        assertEquals(a.mPreferredOrder, b.mPreferredOrder);
        assertEquals(a.installLocation, b.installLocation);
        assertEquals(a.coreApp, b.coreApp);
        assertEquals(a.mRequiredForAllUsers, b.mRequiredForAllUsers);
        assertEquals(a.mCompileSdkVersion, b.mCompileSdkVersion);
        assertEquals(a.mCompileSdkVersionCodename, b.mCompileSdkVersionCodename);
        assertEquals(a.use32bitAbi, b.use32bitAbi);
        assertEquals(a.packageName, b.packageName);
        assertTrue(Arrays.equals(a.splitNames, b.splitNames));
        assertEquals(a.volumeUuid, b.volumeUuid);
        assertEquals(a.codePath, b.codePath);
        assertEquals(a.baseCodePath, b.baseCodePath);
        assertTrue(Arrays.equals(a.splitCodePaths, b.splitCodePaths));
        assertTrue(Arrays.equals(a.splitRevisionCodes, b.splitRevisionCodes));
        assertTrue(Arrays.equals(a.splitFlags, b.splitFlags));
        assertTrue(Arrays.equals(a.splitPrivateFlags, b.splitPrivateFlags));
        assertApplicationInfoEqual(a.applicationInfo, b.applicationInfo);

        assertEquals(a.permissions.size(), b.permissions.size());
        for (int i = 0; i < a.permissions.size(); ++i) {
            assertPermissionsEqual(a.permissions.get(i), b.permissions.get(i));
            assertSame(a.permissions.get(i).owner, a);
            assertSame(b.permissions.get(i).owner, b);
        }

        assertEquals(a.permissionGroups.size(), b.permissionGroups.size());
        for (int i = 0; i < a.permissionGroups.size(); ++i) {
            assertPermissionGroupsEqual(a.permissionGroups.get(i), b.permissionGroups.get(i));
        }

        assertEquals(a.activities.size(), b.activities.size());
        for (int i = 0; i < a.activities.size(); ++i) {
            assertActivitiesEqual(a.activities.get(i), b.activities.get(i));
        }

        assertEquals(a.receivers.size(), b.receivers.size());
        for (int i = 0; i < a.receivers.size(); ++i) {
            assertActivitiesEqual(a.receivers.get(i), b.receivers.get(i));
        }

        assertEquals(a.providers.size(), b.providers.size());
        for (int i = 0; i < a.providers.size(); ++i) {
            assertProvidersEqual(a.providers.get(i), b.providers.get(i));
        }

        assertEquals(a.services.size(), b.services.size());
        for (int i = 0; i < a.services.size(); ++i) {
            assertServicesEqual(a.services.get(i), b.services.get(i));
        }

        assertEquals(a.instrumentation.size(), b.instrumentation.size());
        for (int i = 0; i < a.instrumentation.size(); ++i) {
            assertInstrumentationEqual(a.instrumentation.get(i), b.instrumentation.get(i));
        }

        assertEquals(a.requestedPermissions, b.requestedPermissions);
        assertEquals(a.protectedBroadcasts, b.protectedBroadcasts);
        assertEquals(a.parentPackage, b.parentPackage);
        assertEquals(a.childPackages, b.childPackages);
        assertEquals(a.libraryNames, b.libraryNames);
        assertEquals(a.usesLibraries, b.usesLibraries);
        assertEquals(a.usesOptionalLibraries, b.usesOptionalLibraries);
        assertTrue(Arrays.equals(a.usesLibraryFiles, b.usesLibraryFiles));
        assertEquals(a.mOriginalPackages, b.mOriginalPackages);
        assertEquals(a.mRealPackage, b.mRealPackage);
        assertEquals(a.mAdoptPermissions, b.mAdoptPermissions);
        assertBundleApproximateEquals(a.mAppMetaData, b.mAppMetaData);
        assertEquals(a.mVersionName, b.mVersionName);
        assertEquals(a.mSharedUserId, b.mSharedUserId);
        assertTrue(Arrays.equals(a.mSigningDetails.signatures, b.mSigningDetails.signatures));
        assertTrue(Arrays.equals(a.mLastPackageUsageTimeInMills, b.mLastPackageUsageTimeInMills));
        assertEquals(a.mExtras, b.mExtras);
        assertEquals(a.mRestrictedAccountType, b.mRestrictedAccountType);
        assertEquals(a.mRequiredAccountType, b.mRequiredAccountType);
        assertEquals(a.mOverlayTarget, b.mOverlayTarget);
        assertEquals(a.mOverlayTargetName, b.mOverlayTargetName);
        assertEquals(a.mOverlayCategory, b.mOverlayCategory);
        assertEquals(a.mOverlayPriority, b.mOverlayPriority);
        assertEquals(a.mOverlayIsStatic, b.mOverlayIsStatic);
        assertEquals(a.mSigningDetails.publicKeys, b.mSigningDetails.publicKeys);
        assertEquals(a.mUpgradeKeySets, b.mUpgradeKeySets);
        assertEquals(a.mKeySetMapping, b.mKeySetMapping);
        assertEquals(a.cpuAbiOverride, b.cpuAbiOverride);
        assertTrue(Arrays.equals(a.restrictUpdateHash, b.restrictUpdateHash));
    }

    private static void assertBundleApproximateEquals(Bundle a, Bundle b) {
        if (a == b) {
            return;
        }

        // Force the bundles to be unparceled.
        a.getBoolean("foo");
        b.getBoolean("foo");

        assertEquals(a.toString(), b.toString());
    }

    private static void assertComponentsEqual(PackageParser.Component<?> a,
                                              PackageParser.Component<?> b) {
        assertEquals(a.className, b.className);
        assertBundleApproximateEquals(a.metaData, b.metaData);
        assertEquals(a.getComponentName(), b.getComponentName());

        if (a.intents != null && b.intents != null) {
            assertEquals(a.intents.size(), b.intents.size());
        } else if (a.intents == null || b.intents == null) {
            return;
        }

        for (int i = 0; i < a.intents.size(); ++i) {
            PackageParser.IntentInfo aIntent = a.intents.get(i);
            PackageParser.IntentInfo bIntent = b.intents.get(i);

            assertEquals(aIntent.hasDefault, bIntent.hasDefault);
            assertEquals(aIntent.labelRes, bIntent.labelRes);
            assertEquals(aIntent.nonLocalizedLabel, bIntent.nonLocalizedLabel);
            assertEquals(aIntent.icon, bIntent.icon);
            assertEquals(aIntent.logo, bIntent.logo);
            assertEquals(aIntent.banner, bIntent.banner);
            assertEquals(aIntent.preferred, bIntent.preferred);
        }
    }

    private static void assertPermissionsEqual(PackageParser.Permission a,
                                               PackageParser.Permission b) {
        assertComponentsEqual(a, b);
        assertEquals(a.tree, b.tree);

        // Verify basic flags in PermissionInfo to make sure they're consistent. We don't perform
        // a full structural equality here because the code that serializes them isn't parser
        // specific and is tested elsewhere.
        assertEquals(a.info.protectionLevel, b.info.protectionLevel);
        assertEquals(a.info.group, b.info.group);
        assertEquals(a.info.flags, b.info.flags);

        if (a.group != null && b.group != null) {
            assertPermissionGroupsEqual(a.group, b.group);
        } else if (a.group != null || b.group != null) {
            throw new AssertionError();
        }
    }

    private static void assertInstrumentationEqual(PackageParser.Instrumentation a,
                                                   PackageParser.Instrumentation b) {
        assertComponentsEqual(a, b);

        // Sanity check for InstrumentationInfo.
        assertEquals(a.info.targetPackage, b.info.targetPackage);
        assertEquals(a.info.targetProcesses, b.info.targetProcesses);
        assertEquals(a.info.sourceDir, b.info.sourceDir);
        assertEquals(a.info.publicSourceDir, b.info.publicSourceDir);
    }

    private static void assertServicesEqual(PackageParser.Service a, PackageParser.Service b) {
        assertComponentsEqual(a, b);

        // Sanity check for ServiceInfo.
        assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo);
        assertEquals(a.info.name, b.info.name);
    }

    private static void assertProvidersEqual(PackageParser.Provider a, PackageParser.Provider b) {
        assertComponentsEqual(a, b);

        // Sanity check for ProviderInfo
        assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo);
        assertEquals(a.info.name, b.info.name);
    }

    private static void assertActivitiesEqual(PackageParser.Activity a, PackageParser.Activity b) {
        assertComponentsEqual(a, b);

        // Sanity check for ActivityInfo.
        assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo);
        assertEquals(a.info.name, b.info.name);
    }

    private static void assertPermissionGroupsEqual(PackageParser.PermissionGroup a,
                                                    PackageParser.PermissionGroup b) {
        assertComponentsEqual(a, b);

        // Sanity check for PermissionGroupInfo.
        assertEquals(a.info.name, b.info.name);
        assertEquals(a.info.descriptionRes, b.info.descriptionRes);
    }

    private static void assertApplicationInfoEqual(ApplicationInfo a, ApplicationInfo that) {
        assertEquals(a.descriptionRes, that.descriptionRes);
        assertEquals(a.theme, that.theme);
        assertEquals(a.fullBackupContent, that.fullBackupContent);
        assertEquals(a.uiOptions, that.uiOptions);
        assertEquals(a.flags, that.flags);
        assertEquals(a.privateFlags, that.privateFlags);
        assertEquals(a.requiresSmallestWidthDp, that.requiresSmallestWidthDp);
        assertEquals(a.compatibleWidthLimitDp, that.compatibleWidthLimitDp);
        assertEquals(a.largestWidthLimitDp, that.largestWidthLimitDp);
        assertEquals(a.nativeLibraryRootRequiresIsa, that.nativeLibraryRootRequiresIsa);
        assertEquals(a.uid, that.uid);
        assertEquals(a.minSdkVersion, that.minSdkVersion);
        assertEquals(a.targetSdkVersion, that.targetSdkVersion);
        assertEquals(a.versionCode, that.versionCode);
        assertEquals(a.enabled, that.enabled);
        assertEquals(a.enabledSetting, that.enabledSetting);
        assertEquals(a.installLocation, that.installLocation);
        assertEquals(a.networkSecurityConfigRes, that.networkSecurityConfigRes);
        assertEquals(a.taskAffinity, that.taskAffinity);
        assertEquals(a.permission, that.permission);
        assertEquals(a.processName, that.processName);
        assertEquals(a.className, that.className);
        assertEquals(a.manageSpaceActivityName, that.manageSpaceActivityName);
        assertEquals(a.backupAgentName, that.backupAgentName);
        assertEquals(a.volumeUuid, that.volumeUuid);
        assertEquals(a.scanSourceDir, that.scanSourceDir);
        assertEquals(a.scanPublicSourceDir, that.scanPublicSourceDir);
        assertEquals(a.sourceDir, that.sourceDir);
        assertEquals(a.publicSourceDir, that.publicSourceDir);
        assertTrue(Arrays.equals(a.splitSourceDirs, that.splitSourceDirs));
        assertTrue(Arrays.equals(a.splitPublicSourceDirs, that.splitPublicSourceDirs));
        assertTrue(Arrays.equals(a.resourceDirs, that.resourceDirs));
        assertEquals(a.seInfo, that.seInfo);
        assertTrue(Arrays.equals(a.sharedLibraryFiles, that.sharedLibraryFiles));
        assertEquals(a.dataDir, that.dataDir);
        assertEquals(a.deviceProtectedDataDir, that.deviceProtectedDataDir);
        assertEquals(a.credentialProtectedDataDir, that.credentialProtectedDataDir);
        assertEquals(a.nativeLibraryDir, that.nativeLibraryDir);
        assertEquals(a.secondaryNativeLibraryDir, that.secondaryNativeLibraryDir);
        assertEquals(a.nativeLibraryRootDir, that.nativeLibraryRootDir);
        assertEquals(a.primaryCpuAbi, that.primaryCpuAbi);
        assertEquals(a.secondaryCpuAbi, that.secondaryCpuAbi);
    }

    public static void setKnownFields(PackageParser.Package pkg) {
        pkg.baseRevisionCode = 100;
        pkg.baseHardwareAccelerated = true;
        pkg.mVersionCode = 100;
        pkg.mSharedUserLabel = 100;
        pkg.mPreferredOrder = 100;
        pkg.installLocation = 100;
        pkg.coreApp = true;
        pkg.mRequiredForAllUsers = true;
        pkg.use32bitAbi = true;
        pkg.packageName = "foo";
        pkg.splitNames = new String[] { "foo2" };
        pkg.volumeUuid = "foo3";
        pkg.codePath = "foo4";
        pkg.baseCodePath = "foo5";
        pkg.splitCodePaths = new String[] { "foo6" };
        pkg.splitRevisionCodes = new int[] { 100 };
        pkg.splitFlags = new int[] { 100 };
        pkg.splitPrivateFlags = new int[] { 100 };
        pkg.applicationInfo = new ApplicationInfo();

        pkg.permissions.add(new PackageParser.Permission(pkg, (String) null));
        pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg, ID_NULL, ID_NULL, ID_NULL));

        final PackageParser.ParseComponentArgs dummy = new PackageParser.ParseComponentArgs(
                pkg, new String[1], 0, 0, 0, 0, 0, 0, null, 0, 0, 0);

        pkg.activities.add(new PackageParser.Activity(dummy, new ActivityInfo()));
        pkg.receivers.add(new PackageParser.Activity(dummy, new ActivityInfo()));
        pkg.providers.add(new PackageParser.Provider(dummy, new ProviderInfo()));
        pkg.services.add(new PackageParser.Service(dummy, new ServiceInfo()));
        pkg.instrumentation.add(new PackageParser.Instrumentation(dummy, new InstrumentationInfo()));
        pkg.requestedPermissions.add("foo7");
        pkg.implicitPermissions.add("foo25");

        pkg.protectedBroadcasts = new ArrayList<>();
        pkg.protectedBroadcasts.add("foo8");

        pkg.parentPackage = new PackageParser.Package("foo9");

        pkg.childPackages = new ArrayList<>();
        pkg.childPackages.add(new PackageParser.Package("bar"));

        pkg.staticSharedLibName = "foo23";
        pkg.staticSharedLibVersion = 100;
        pkg.usesStaticLibraries = new ArrayList<>();
        pkg.usesStaticLibraries.add("foo23");
        pkg.usesStaticLibrariesCertDigests = new String[1][];
        pkg.usesStaticLibrariesCertDigests[0] = new String[] { "digest" };
        pkg.usesStaticLibrariesVersions = new long[] { 100 };

        pkg.libraryNames = new ArrayList<>();
        pkg.libraryNames.add("foo10");

        pkg.usesLibraries = new ArrayList<>();
        pkg.usesLibraries.add("foo11");

        pkg.usesOptionalLibraries = new ArrayList<>();
        pkg.usesOptionalLibraries.add("foo12");

        pkg.usesLibraryFiles = new String[] { "foo13"};

        pkg.usesLibraryInfos = new ArrayList<>();
        pkg.usesLibraryInfos.add(
                new SharedLibraryInfo(null, null, null, null, 0L, 0, null, null, null));

        pkg.mOriginalPackages = new ArrayList<>();
        pkg.mOriginalPackages.add("foo14");

        pkg.mRealPackage = "foo15";

        pkg.mAdoptPermissions = new ArrayList<>();
        pkg.mAdoptPermissions.add("foo16");

        pkg.mAppMetaData = new Bundle();
        pkg.mVersionName = "foo17";
        pkg.mSharedUserId = "foo18";
        pkg.mSigningDetails =
                new PackageParser.SigningDetails(
                        new Signature[] { new Signature(new byte[16]) },
                        2,
                        new ArraySet<>(),
                        null);
        pkg.mExtras = new Bundle();
        pkg.mRestrictedAccountType = "foo19";
        pkg.mRequiredAccountType = "foo20";
        pkg.mOverlayTarget = "foo21";
        pkg.mOverlayPriority = 100;
        pkg.mUpgradeKeySets = new ArraySet<>();
        pkg.mKeySetMapping = new ArrayMap<>();
        pkg.cpuAbiOverride = "foo22";
        pkg.restrictUpdateHash = new byte[16];

        pkg.preferredActivityFilters = new ArrayList<>();
        pkg.preferredActivityFilters.add(new PackageParser.ActivityIntentInfo(
                new PackageParser.Activity(dummy, new ActivityInfo())));

        pkg.configPreferences = new ArrayList<>();
        pkg.configPreferences.add(new ConfigurationInfo());

        pkg.reqFeatures = new ArrayList<>();
        pkg.reqFeatures.add(new FeatureInfo());

        pkg.featureGroups = new ArrayList<>();
        pkg.featureGroups.add(new FeatureGroupInfo());

        pkg.mCompileSdkVersionCodename = "foo23";
        pkg.mCompileSdkVersion = 100;
        pkg.mVersionCodeMajor = 100;

        pkg.mOverlayCategory = "foo24";
        pkg.mOverlayIsStatic = true;
        pkg.mOverlayTargetName = "foo26";

        pkg.baseHardwareAccelerated = true;
        pkg.coreApp = true;
        pkg.mRequiredForAllUsers = true;
        pkg.visibleToInstantApps = true;
        pkg.use32bitAbi = true;
    }

    private static void assertAllFieldsExist(PackageParser.Package pkg) throws Exception {
        Field[] fields = PackageParser.Package.class.getDeclaredFields();

        Set<String> nonSerializedFields = new HashSet<>();
        nonSerializedFields.add("mExtras");
        nonSerializedFields.add("packageUsageTimeMillis");
        nonSerializedFields.add("isStub");

        for (Field f : fields) {
            final Class<?> fieldType = f.getType();

            if (nonSerializedFields.contains(f.getName())) {
                continue;
            }

            if (List.class.isAssignableFrom(fieldType)) {
                // Sanity check for list fields: Assume they're non-null and contain precisely
                // one element.
                List<?> list = (List<?>) f.get(pkg);
                assertNotNull("List was null: " + f, list);
                assertEquals(1, list.size());
            } else if (fieldType.getComponentType() != null) {
                // Sanity check for array fields: Assume they're non-null and contain precisely
                // one element.
                Object array = f.get(pkg);
                assertNotNull(Array.get(array, 0));
            } else if (fieldType == String.class) {
                // String fields: Check that they're set to "foo".
                String value = (String) f.get(pkg);

                assertTrue("Bad value for field: " + f, value != null && value.startsWith("foo"));
            } else if (fieldType == int.class) {
                // int fields: Check that they're set to 100.
                int value = (int) f.get(pkg);
                assertEquals("Bad value for field: " + f, 100, value);
            } else if (fieldType == boolean.class) {
                // boolean fields: Check that they're set to true.
                boolean value = (boolean) f.get(pkg);
                assertEquals("Bad value for field: " + f, true, value);
            } else {
                // All other fields: Check that they're set.
                Object o = f.get(pkg);
                assertNotNull("Field was null: " + f, o);
            }
        }
    }
}

