/*
 * Copyright (C) 2020 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.parsing;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.apex.ApexInfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.content.pm.PermissionInfo;
import android.content.pm.parsing.component.ParsedComponent;
import android.content.pm.parsing.component.ParsedPermission;
import android.os.Build;
import android.os.Bundle;
import android.os.FileUtils;
import android.platform.test.annotations.Presubmit;
import android.util.SparseIntArray;

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

import com.android.frameworks.servicestests.R;
import com.android.internal.util.ArrayUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.ParsedPackage;

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

import java.io.File;
import java.io.InputStream;
import java.util.function.Function;

/**
 * {@link ParsedPackage} was moved to the server, so this test moved along with it.
 *
 * This should be eventually refactored to a comprehensive parsing test, combined with its
 * server variant in the parent package.
 *
 * TODO(b/135203078): Remove this test and replicate the cases in the actual com.android.server
 *  variant.
 */
@Presubmit
@SmallTest
@RunWith(AndroidJUnit4.class)
public class PackageParserLegacyCoreTest {
    private static final String RELEASED = null;
    private static final String OLDER_PRE_RELEASE = "A";
    private static final String PRE_RELEASE = "B";
    private static final String NEWER_PRE_RELEASE = "C";

    // Codenames with a fingerprint attached to them. These may only be present in the apps
    // declared min SDK and not as platform codenames.
    private static final String OLDER_PRE_RELEASE_WITH_FINGERPRINT = "A.fingerprint";
    private static final String PRE_RELEASE_WITH_FINGERPRINT = "B.fingerprint";
    private static final String NEWER_PRE_RELEASE_WITH_FINGERPRINT = "C.fingerprint";

    private static final String[] CODENAMES_RELEASED = { /* empty */};
    private static final String[] CODENAMES_PRE_RELEASE = {PRE_RELEASE};

    private static final int OLDER_VERSION = 10;
    private static final int PLATFORM_VERSION = 20;
    private static final int NEWER_VERSION = 30;

    private void verifyComputeMinSdkVersion(int minSdkVersion, String minSdkCodename,
            boolean isPlatformReleased, int expectedMinSdk) {
        final String[] outError = new String[1];
        final int result = PackageParser.computeMinSdkVersion(
                minSdkVersion,
                minSdkCodename,
                PLATFORM_VERSION,
                isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
                outError);

        assertEquals("Error msg: " + outError[0], expectedMinSdk, result);

        if (expectedMinSdk == -1) {
            assertNotNull(outError[0]);
        } else {
            assertNull(outError[0]);
        }
    }

    @Test
    public void testComputeMinSdkVersion_preReleasePlatform() {
        // Do allow older release minSdkVersion on pre-release platform.
        // APP: Released API 10
        // DEV: Pre-release API 20
        verifyComputeMinSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION);

        // Do allow same release minSdkVersion on pre-release platform.
        // APP: Released API 20
        // DEV: Pre-release API 20
        verifyComputeMinSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION);

        // Don't allow newer release minSdkVersion on pre-release platform.
        // APP: Released API 30
        // DEV: Pre-release API 20
        verifyComputeMinSdkVersion(NEWER_VERSION, RELEASED, false, -1);

        // Don't allow older pre-release minSdkVersion on pre-release platform.
        // APP: Pre-release API 10
        // DEV: Pre-release API 20
        verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1);
        verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);

        // Do allow same pre-release minSdkVersion on pre-release platform,
        // but overwrite the specified version with CUR_DEVELOPMENT.
        // APP: Pre-release API 20
        // DEV: Pre-release API 20
        verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false,
                Build.VERSION_CODES.CUR_DEVELOPMENT);
        verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, false,
                Build.VERSION_CODES.CUR_DEVELOPMENT);


        // Don't allow newer pre-release minSdkVersion on pre-release platform.
        // APP: Pre-release API 30
        // DEV: Pre-release API 20
        verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1);
        verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);
    }

    @Test
    public void testComputeMinSdkVersion_releasedPlatform() {
        // Do allow older release minSdkVersion on released platform.
        // APP: Released API 10
        // DEV: Released API 20
        verifyComputeMinSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION);

        // Do allow same release minSdkVersion on released platform.
        // APP: Released API 20
        // DEV: Released API 20
        verifyComputeMinSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION);

        // Don't allow newer release minSdkVersion on released platform.
        // APP: Released API 30
        // DEV: Released API 20
        verifyComputeMinSdkVersion(NEWER_VERSION, RELEASED, true, -1);

        // Don't allow older pre-release minSdkVersion on released platform.
        // APP: Pre-release API 10
        // DEV: Released API 20
        verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1);
        verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);

        // Don't allow same pre-release minSdkVersion on released platform.
        // APP: Pre-release API 20
        // DEV: Released API 20
        verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1);
        verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, true, -1);


        // Don't allow newer pre-release minSdkVersion on released platform.
        // APP: Pre-release API 30
        // DEV: Released API 20
        verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1);
        verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);
    }

    private void verifyComputeTargetSdkVersion(int targetSdkVersion, String targetSdkCodename,
            boolean isPlatformReleased, int expectedTargetSdk) {
        final String[] outError = new String[1];
        final int result = PackageParser.computeTargetSdkVersion(
                targetSdkVersion,
                targetSdkCodename,
                isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
                outError);

        assertEquals(result, expectedTargetSdk);

        if (expectedTargetSdk == -1) {
            assertNotNull(outError[0]);
        } else {
            assertNull(outError[0]);
        }
    }

    @Test
    public void testComputeTargetSdkVersion_preReleasePlatform() {
        // Do allow older release targetSdkVersion on pre-release platform.
        // APP: Released API 10
        // DEV: Pre-release API 20
        verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION);

        // Do allow same release targetSdkVersion on pre-release platform.
        // APP: Released API 20
        // DEV: Pre-release API 20
        verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION);

        // Do allow newer release targetSdkVersion on pre-release platform.
        // APP: Released API 30
        // DEV: Pre-release API 20
        verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, false, NEWER_VERSION);

        // Don't allow older pre-release targetSdkVersion on pre-release platform.
        // APP: Pre-release API 10
        // DEV: Pre-release API 20
        verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1);
        verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);


        // Do allow same pre-release targetSdkVersion on pre-release platform,
        // but overwrite the specified version with CUR_DEVELOPMENT.
        // APP: Pre-release API 20
        // DEV: Pre-release API 20
        verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false,
                Build.VERSION_CODES.CUR_DEVELOPMENT);
        verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, false,
                Build.VERSION_CODES.CUR_DEVELOPMENT);


        // Don't allow newer pre-release targetSdkVersion on pre-release platform.
        // APP: Pre-release API 30
        // DEV: Pre-release API 20
        verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1);
        verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, false, -1);
    }

    @Test
    public void testComputeTargetSdkVersion_releasedPlatform() {
        // Do allow older release targetSdkVersion on released platform.
        // APP: Released API 10
        // DEV: Released API 20
        verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION);

        // Do allow same release targetSdkVersion on released platform.
        // APP: Released API 20
        // DEV: Released API 20
        verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION);

        // Do allow newer release targetSdkVersion on released platform.
        // APP: Released API 30
        // DEV: Released API 20
        verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, true, NEWER_VERSION);

        // Don't allow older pre-release targetSdkVersion on released platform.
        // APP: Pre-release API 10
        // DEV: Released API 20
        verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1);
        verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);

        // Don't allow same pre-release targetSdkVersion on released platform.
        // APP: Pre-release API 20
        // DEV: Released API 20
        verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1);
        verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE_WITH_FINGERPRINT, true, -1);


        // Don't allow newer pre-release targetSdkVersion on released platform.
        // APP: Pre-release API 30
        // DEV: Released API 20
        verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1);
        verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE_WITH_FINGERPRINT, true, -1);
    }

    /**
     * Unit test for PackageParser.getActivityConfigChanges().
     * If the bit is 1 in the original configChanges, it is still 1 in the final configChanges.
     * If the bit is 0 in the original configChanges and the bit is not set to 1 in
     * recreateOnConfigChanges, the bit is changed to 1 in the final configChanges by default.
     */
    @Test
    public void testGetActivityConfigChanges() {
        // Not set in either configChanges or recreateOnConfigChanges.
        int configChanges = 0x0000; // 00000000.
        int recreateOnConfigChanges = 0x0000; // 00000000.
        int finalConfigChanges =
                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
        assertEquals(0x0003, finalConfigChanges); // Should be 00000011.

        // Not set in configChanges, but set in recreateOnConfigChanges.
        configChanges = 0x0000; // 00000000.
        recreateOnConfigChanges = 0x0003; // 00000011.
        finalConfigChanges =
                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
        assertEquals(0x0000, finalConfigChanges); // Should be 00000000.

        // Set in configChanges.
        configChanges = 0x0003; // 00000011.
        recreateOnConfigChanges = 0X0000; // 00000000.
        finalConfigChanges =
                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
        assertEquals(0x0003, finalConfigChanges); // Should be 00000011.

        recreateOnConfigChanges = 0x0003; // 00000011.
        finalConfigChanges =
                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
        assertEquals(0x0003, finalConfigChanges); // Should still be 00000011.

        // Other bit set in configChanges.
        configChanges = 0x0080; // 10000000, orientation.
        recreateOnConfigChanges = 0x0000; // 00000000.
        finalConfigChanges =
                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
        assertEquals(0x0083, finalConfigChanges); // Should be 10000011.
    }

    /**
     * Copies a specified {@code resourceId} to a file. Returns a non-null file if the copy
     * succeeded, or {@code null} otherwise.
     */
    File copyRawResourceToFile(String baseName, int resourceId) throws Exception {
        // Copy the resource to a file.
        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
        InputStream is = context.getResources().openRawResource(resourceId);
        File outFile = null;
        try {
            outFile = new File(context.getFilesDir(), baseName);
            assertTrue(FileUtils.copyToFile(is, outFile));
            return outFile;
        } catch (Exception e) {
            if (outFile != null) {
                outFile.delete();
            }

            return null;
        }
    }

    /**
     * Attempts to parse a package.
     *
     * APKs are put into coretests/apks/packageparser_*.
     *
     * @param apkFileName   temporary file name to store apk extracted from resources
     * @param apkResourceId identifier of the apk as a resource
     */
    ParsedPackage parsePackage(String apkFileName, int apkResourceId,
            Function<ParsedPackage, ParsedPackage> converter) throws Exception {
        // Copy the resource to a file.
        File outFile = null;
        try {
            outFile = copyRawResourceToFile(apkFileName, apkResourceId);
            return converter.apply(new TestPackageParser2()
                    .parsePackage(outFile, 0 /* flags */, false));
        } finally {
            if (outFile != null) {
                outFile.delete();
            }
        }
    }

    /**
     * Asserts basic properties about a component.
     */
    private void assertComponent(String className, int numIntents, ParsedComponent component) {
        assertEquals(className, component.getName());
        assertEquals(numIntents, component.getIntents().size());
    }

    /**
     * Asserts four regularly-named components of each type: one Activity, one Service, one
     * Provider, and one Receiver.
     *
     * @param template templated string with %s subbed with Activity, Service, Provider, Receiver
     */
    private void assertOneComponentOfEachType(String template, AndroidPackage p) {
        assertEquals(1, p.getActivities().size());
        assertComponent(String.format(template, "Activity"),
                0 /* intents */, p.getActivities().get(0));
        assertEquals(1, p.getServices().size());
        assertComponent(String.format(template, "Service"),
                0 /* intents */, p.getServices().get(0));
        assertEquals(1, p.getProviders().size());
        assertComponent(String.format(template, "Provider"),
                0 /* intents */, p.getProviders().get(0));
        assertEquals(1, p.getReceivers().size());
        assertComponent(String.format(template, "Receiver"),
                0 /* intents */, p.getReceivers().get(0));
    }

    private void assertPermission(String name, int protectionLevel, ParsedPermission permission) {
        assertEquals(name, permission.getName());
        assertEquals(protectionLevel, permission.getProtection());
    }

    private void assertMetadata(Bundle b, String... keysAndValues) {
        assertTrue("Odd number of elements in keysAndValues", (keysAndValues.length % 2) == 0);

        assertNotNull(b);
        assertEquals(keysAndValues.length / 2, b.size());

        for (int i = 0; i < keysAndValues.length; i += 2) {
            final String key = keysAndValues[i];
            final String value = keysAndValues[i + 1];

            assertEquals(value, b.getString(key));
        }
    }

    // TODO Add a "_cached" test for testMultiPackageComponents() too, after fixing b/64295061.
    // Package.writeToParcel can't handle circular package references.

    @Test
    public void testPackageWithComponents_no_cache() throws Exception {
        checkPackageWithComponents(p -> p);
    }

    @Test
    public void testPackageWithComponents_cached() throws Exception {
        checkPackageWithComponents(p ->
                PackageCacher.fromCacheEntryStatic(PackageCacher.toCacheEntryStatic(p)));
    }

    private void checkPackageWithComponents(
            Function<ParsedPackage, ParsedPackage> converter) throws Exception {
        ParsedPackage p = parsePackage(
                "install_complete_package_info.apk", R.raw.install_complete_package_info,
                converter);
        String packageName = "com.android.frameworks.coretests.install_complete_package_info";

        assertEquals(packageName, p.getPackageName());
        assertEquals(1, p.getPermissions().size());
        assertPermission(
                "com.android.frameworks.coretests.install_complete_package_info.test_permission",
                PermissionInfo.PROTECTION_NORMAL, p.getPermissions().get(0));

        findAndRemoveAppDetailsActivity(p);

        assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", p);

        assertMetadata(p.getMetaData(),
                "key1", "value1",
                "key2", "this_is_app");
        assertMetadata(p.getActivities().get(0).getMetaData(),
                "key1", "value1",
                "key2", "this_is_activity");
        assertMetadata(p.getServices().get(0).getMetaData(),
                "key1", "value1",
                "key2", "this_is_service");
        assertMetadata(p.getReceivers().get(0).getMetaData(),
                "key1", "value1",
                "key2", "this_is_receiver");
        assertMetadata(p.getProviders().get(0).getMetaData(),
                "key1", "value1",
                "key2", "this_is_provider");

    }

    private void findAndRemoveAppDetailsActivity(ParsedPackage p) {
        // Hidden "app details" activity is added to every package.
        boolean foundAppDetailsActivity = false;
        for (int i = 0; i < ArrayUtils.size(p.getActivities()); i++) {
            if (p.getActivities().get(i).getClassName().equals(
                    PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME)) {
                foundAppDetailsActivity = true;
                p.getActivities().remove(i);
                break;
            }
        }
        assertTrue("Did not find app details activity", foundAppDetailsActivity);
    }

    @Test
    public void testPackageWithIntentFilters_no_cache() throws Exception {
        checkPackageWithIntentFilters(p -> p);
    }

    @Test
    public void testPackageWithIntentFilters_cached() throws Exception {
        checkPackageWithIntentFilters(p ->
                PackageCacher.fromCacheEntryStatic(PackageCacher.toCacheEntryStatic(p)));
    }

    private void checkPackageWithIntentFilters(
            Function<ParsedPackage, ParsedPackage> converter) throws Exception {
        ParsedPackage p = parsePackage(
                "install_intent_filters.apk", R.raw.install_intent_filters,
                converter);
        String packageName = "com.android.frameworks.servicestests.install_intent_filters";

        assertEquals(packageName, p.getPackageName());

        findAndRemoveAppDetailsActivity(p);

        assertEquals("Expected exactly one activity", 1, p.getActivities().size());
        assertEquals("Expected exactly one intent filter",
                1, p.getActivities().get(0).getIntents().size());
        assertEquals("Expected exactly one mime group in intent filter",
                1, p.getActivities().get(0).getIntents().get(0).countMimeGroups());
        assertTrue("Did not find expected mime group 'mime_group_1'",
                p.getActivities().get(0).getIntents().get(0).hasMimeGroup("mime_group_1"));
    }

    @Test
    public void testApexPackageInfoGeneration() throws Exception {
        String apexModuleName = "com.android.tzdata.apex";
        File apexFile = copyRawResourceToFile(apexModuleName,
                R.raw.com_android_tzdata);
        ApexInfo apexInfo = new ApexInfo();
        apexInfo.isActive = true;
        apexInfo.isFactory = false;
        apexInfo.moduleName = apexModuleName;
        apexInfo.modulePath = apexFile.getPath();
        apexInfo.versionCode = 191000070;
        int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES;

        PackageParser pp = new PackageParser();
        PackageParser.Package p = pp.parsePackage(apexFile, flags, false);
        PackageParser.collectCertificates(p, false);
        PackageInfo pi = PackageParser.generatePackageInfo(p, apexInfo, flags);

        assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
        assertTrue(pi.applicationInfo.enabled);
        assertEquals(28, pi.applicationInfo.targetSdkVersion);
        assertEquals(191000070, pi.applicationInfo.longVersionCode);
        assertNotNull(pi.applicationInfo.metaData);
        assertEquals(apexFile.getPath(), pi.applicationInfo.sourceDir);
        assertEquals("Bundle[{com.android.vending.derived.apk.id=1}]",
                pi.applicationInfo.metaData.toString());

        assertEquals("com.google.android.tzdata", pi.packageName);
        assertEquals(191000070, pi.getLongVersionCode());
        assertNotNull(pi.signingInfo);
        assertTrue(pi.signingInfo.getApkContentsSigners().length > 0);
        assertTrue(pi.isApex);
        assertTrue((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0);
        assertTrue((pi.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0);
    }

    @Test
    public void testUsesSdk() throws Exception {
        ParsedPackage pkg =
                parsePackage("install_uses_sdk.apk_r0", R.raw.install_uses_sdk_r0, x -> x);
        SparseIntArray minExtVers = pkg.getMinExtensionVersions();
        assertEquals(1, minExtVers.size());
        assertEquals(0, minExtVers.get(10000, -1));

        try {
            parsePackage("install_uses_sdk.apk_r5", R.raw.install_uses_sdk_r5, x -> x);
            fail("Expected parsing exception due to incompatible extension SDK version");
        } catch (PackageParser.PackageParserException expected) {
            assertEquals(PackageManager.INSTALL_FAILED_OLDER_SDK, expected.error);
        }
        try {
            parsePackage("install_uses_sdk.apk_q0", R.raw.install_uses_sdk_q0, x -> x);
            fail("Expected parsing exception due to non-existent extension SDK");
        } catch (PackageParser.PackageParserException expected) {
            assertEquals(PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, expected.error);
        }
        try {
            parsePackage("install_uses_sdk.apk_r", R.raw.install_uses_sdk_r, x -> x);
            fail("Expected parsing exception due to unspecified extension SDK version");
        } catch (PackageParser.PackageParserException expected) {
            assertEquals(PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, expected.error);
        }
        try {
            parsePackage("install_uses_sdk.apk_0", R.raw.install_uses_sdk_0, x -> x);
            fail("Expected parsing exception due to unspecified extension SDK");
        } catch (PackageParser.PackageParserException expected) {
            assertEquals(PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, expected.error);
        }

    }
}
