/*
 * 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 android.content.pm.cts;

import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256;
import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512;
import static android.content.pm.Checksum.TYPE_WHOLE_MD5;
import static android.content.pm.Checksum.TYPE_WHOLE_MERKLE_ROOT_4K_SHA256;
import static android.content.pm.Checksum.TYPE_WHOLE_SHA1;
import static android.content.pm.Checksum.TYPE_WHOLE_SHA256;
import static android.content.pm.Checksum.TYPE_WHOLE_SHA512;
import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;
import static android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES;
import static android.content.pm.PackageManager.TRUST_ALL;
import static android.content.pm.PackageManager.TRUST_NONE;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertThrows;

import android.app.UiAutomation;
import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApkChecksum;
import android.content.pm.Checksum;
import android.content.pm.DataLoaderParams;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.Session;
import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.pm.cts.util.AbandonAllPackageSessionsRule;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
import android.platform.test.annotations.AppModeFull;
import android.util.ExceptionUtils;

import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.internal.util.HexDump;
import com.android.server.pm.ApkChecksums;
import com.android.server.pm.PackageManagerShellCommandDataLoader;
import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata;

import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import javax.annotation.Nonnull;

@RunWith(AndroidJUnit4.class)
@AppModeFull
public class ChecksumsTest {
    private static final String CTS_PACKAGE_NAME = "android.content.cts";
    private static final String V2V3_PACKAGE_NAME = "android.content.cts";
    private static final String V4_PACKAGE_NAME = "com.example.helloworld";
    private static final String FIXED_PACKAGE_NAME = "android.appsecurity.cts.tinyapp";
    private static final String FIXED_FSVERITY_PACKAGE_NAME =
            "android.appsecurity.cts.apkveritytestapp";

    private static final String TEST_APK_PATH = "/data/local/tmp/cts/content/";

    private static final String TEST_V4_APK = "HelloWorld5.apk";
    private static final String TEST_V4_SPLIT0 = "HelloWorld5_hdpi-v4.apk";
    private static final String TEST_V4_SPLIT1 = "HelloWorld5_mdpi-v4.apk";
    private static final String TEST_V4_SPLIT2 = "HelloWorld5_xhdpi-v4.apk";
    private static final String TEST_V4_SPLIT3 = "HelloWorld5_xxhdpi-v4.apk";
    private static final String TEST_V4_SPLIT4 = "HelloWorld5_xxxhdpi-v4.apk";

    private static final String TEST_FIXED_APK = "CtsPkgInstallTinyAppV2V3V4.apk";
    private static final String TEST_FIXED_APK_DIGESTS_FILE =
            "CtsPkgInstallTinyAppV2V3V4.digests";
    private static final String TEST_FIXED_APK_DIGESTS_SIGNATURE =
            "CtsPkgInstallTinyAppV2V3V4.digests.signature";
    private static final String TEST_CERTIFICATE = "test-cert.x509.pem";
    private static final String TEST_FIXED_APK_V1 = "CtsPkgInstallTinyAppV1.apk";
    private static final String TEST_FIXED_APK_SHA512 =
            "CtsPkgInstallTinyAppV2V3V4-Sha512withEC.apk";
    private static final String TEST_FIXED_APK_VERITY = "CtsPkgInstallTinyAppV2V3V4-Verity.apk";

    private static final String TEST_FIXED_APK_FSVERITY = "CtsApkVerityTestAppPrebuilt.apk";
    private static final String TEST_FIXED_APK_FSVERITY_FSVSIG =
            "CtsApkVerityTestAppPrebuilt.apk.fsv_sig";
    private static final String TEST_FIXED_APK_FSVERITY_SHA256_ARM64 =
            "84c9974e74258a9c5abbc8a797358fe8ebf8918edf62383ea621e9e9e6461864";
    private static final String TEST_FIXED_APK_FSVERITY_SHA256_X86_64 =
            "5073070ee9e9a7821b4044b457d95a2bb81f349ba32d31acd0952e4a2617075a";

    private static final String TEST_FIXED_APK_V2_SHA256 =
            "1eec9e86e322b8d7e48e255fc3f2df2dbc91036e63982ff9850597c6a37bbeb3";
    private static final String TEST_FIXED_APK_SHA256 =
            "91aa30c1ce8d0474052f71cb8210691d41f534989c5521e27e794ec4f754c5ef";
    private static final String TEST_FIXED_APK_MD5 = "c19868da017dc01467169f8ea7c5bc57";
    private static final Checksum[] TEST_FIXED_APK_DIGESTS = new Checksum[]{
            new Checksum(TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256,
                    hexStringToBytes(TEST_FIXED_APK_V2_SHA256)),
            new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(TEST_FIXED_APK_SHA256)),
            new Checksum(TYPE_WHOLE_MD5, hexStringToBytes(TEST_FIXED_APK_MD5))};
    private static final Checksum[] TEST_FIXED_APK_WRONG_DIGESTS = new Checksum[]{
            new Checksum(TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256, hexStringToBytes("850597c6a37bbeb3")),
            new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(TEST_FIXED_APK_SHA256)),
            new Checksum(TYPE_WHOLE_MD5, hexStringToBytes(TEST_FIXED_APK_MD5))};

    private static final String PRIMARY_ABI = Build.SUPPORTED_ABIS[0];

    /** Default is to not use fs-verity since it depends on kernel support. */
    private static final int FSVERITY_DISABLED = 0;

    /** Standard fs-verity. */
    private static final int FSVERITY_ENABLED = 2;

    private static final byte[] NO_SIGNATURE = null;

    private static final int ALL_CHECKSUMS =
            TYPE_WHOLE_MERKLE_ROOT_4K_SHA256 | TYPE_WHOLE_MD5 | TYPE_WHOLE_SHA1 | TYPE_WHOLE_SHA256
                    | TYPE_WHOLE_SHA512
                    | TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256 | TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512;

    private static UiAutomation getUiAutomation() {
        return InstrumentationRegistry.getInstrumentation().getUiAutomation();
    }

    private static Context getContext() {
        return InstrumentationRegistry.getContext();
    }

    private static PackageManager getPackageManager() {
        return getContext().getPackageManager();
    }

    private static PackageInstaller getPackageInstaller() {
        return getPackageManager().getPackageInstaller();
    }

    @Rule
    public AbandonAllPackageSessionsRule mAbandonSessionsRule = new AbandonAllPackageSessionsRule();

    @Before
    public void onBefore() throws Exception {
        uninstallPackageSilently(V4_PACKAGE_NAME);
        assertFalse(isAppInstalled(V4_PACKAGE_NAME));
        uninstallPackageSilently(FIXED_PACKAGE_NAME);
        assertFalse(isAppInstalled(FIXED_PACKAGE_NAME));
        uninstallPackageSilently(FIXED_FSVERITY_PACKAGE_NAME);
        assertFalse(isAppInstalled(FIXED_FSVERITY_PACKAGE_NAME));
    }

    @After
    public void onAfter() throws Exception {
        uninstallPackageSilently(V4_PACKAGE_NAME);
        assertFalse(isAppInstalled(V4_PACKAGE_NAME));
        uninstallPackageSilently(FIXED_PACKAGE_NAME);
        assertFalse(isAppInstalled(FIXED_PACKAGE_NAME));
        uninstallPackageSilently(FIXED_FSVERITY_PACKAGE_NAME);
        assertFalse(isAppInstalled(FIXED_FSVERITY_PACKAGE_NAME));
    }

    @Test
    public void testNameNotFound() throws Exception {
        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        assertThrows(PackageManager.NameNotFoundException.class,
                () -> pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_NONE, receiver));
    }

    @Test
    public void testReadWriteChecksums() throws Exception {
        // Read checksums from file and confirm they are the same as hardcoded.
        checkStoredChecksums(TEST_FIXED_APK_DIGESTS, TEST_FIXED_APK_DIGESTS_FILE);

        // Write checksums and confirm that the file stays the same.
        try (ByteArrayOutputStream os = new ByteArrayOutputStream();
             DataOutputStream dos = new DataOutputStream(os)) {
            for (Checksum checksum : TEST_FIXED_APK_DIGESTS) {
                Checksum.writeToStream(dos, checksum);
            }
            final byte[] fileBytes = Files.readAllBytes(
                    Paths.get(createApkPath(TEST_FIXED_APK_DIGESTS_FILE)));
            final byte[] localBytes = os.toByteArray();
            Assert.assertArrayEquals(fileBytes, localBytes);
        }
    }

    @Test
    public void testDefaultChecksums() throws Exception {
        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(V2V3_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
    }

    @Test
    public void testSplitsDefaultChecksums() throws Exception {
        installSplits(new String[]{TEST_V4_APK, TEST_V4_SPLIT0, TEST_V4_SPLIT1, TEST_V4_SPLIT2,
                TEST_V4_SPLIT3, TEST_V4_SPLIT4});
        assertTrue(isAppInstalled(V4_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 6);
        // v2/v3 signature use 1M merkle tree.
        assertEquals(checksums[0].getSplitName(), null);
        assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(checksums[1].getSplitName(), "config.hdpi");
        assertEquals(checksums[1].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(checksums[2].getSplitName(), "config.mdpi");
        assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(checksums[3].getSplitName(), "config.xhdpi");
        assertEquals(checksums[3].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(checksums[4].getSplitName(), "config.xxhdpi");
        assertEquals(checksums[4].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(checksums[5].getSplitName(), "config.xxxhdpi");
        assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
    }

    @Test
    public void testFixedDefaultChecksums() throws Exception {
        installPackage(TEST_FIXED_APK);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        // v2/v3 signature use 1M merkle tree.
        assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertNull(checksums[0].getInstallerCertificate());
    }

    @Test
    public void testFixedV1DefaultChecksums() throws Exception {
        installPackage(TEST_FIXED_APK_V1);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 0);
    }

    @Test
    public void testFixedSha512DefaultChecksums() throws Exception {
        installPackage(TEST_FIXED_APK_SHA512);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        // v2/v3 signature use 1M merkle tree.
        assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512);
        assertEquals(bytesToHexString(checksums[0].getValue()),
                "6b866e8a54a3e358dfc20007960fb96123845f6c6d6c45f5fddf88150d71677f"
                        + "4c3081a58921c88651f7376118aca312cf764b391cdfb8a18c6710f9f27916a0");
        assertNull(checksums[0].getInstallerCertificate());
    }

    @LargeTest
    @Test
    public void testFixedFSVerityDefaultChecksums() throws Exception {
        Assume.assumeTrue(isApkVerityEnabled());
        installApkWithFSVerity(TEST_FIXED_APK_FSVERITY, TEST_FIXED_APK_FSVERITY_FSVSIG);
        assertTrue(isAppInstalled(FIXED_FSVERITY_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_FSVERITY_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 2);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256);
        if ("x86_64".equals(PRIMARY_ABI) || "x86".equals(PRIMARY_ABI)) {
            assertEquals(bytesToHexString(checksums[0].getValue()),
                    TEST_FIXED_APK_FSVERITY_SHA256_X86_64);
            assertEquals(bytesToHexString(checksums[1].getValue()),
                    "6f7cfa569c4a25d7241e26c1c8ff274badbdefd7854d91b842b1a97a985d5917");
        } else if ("arm64-v8a".equals(PRIMARY_ABI) || "armeabi".equals(PRIMARY_ABI)
                || "armeabi-v7a".equals(PRIMARY_ABI)) {
            assertEquals(bytesToHexString(checksums[0].getValue()),
                    TEST_FIXED_APK_FSVERITY_SHA256_ARM64);
            assertEquals(bytesToHexString(checksums[1].getValue()),
                    "8c61bc2548521aa0005276af68e42253957e1e24c122f7d8bf10f1832d4014e5");
        } else {
            Assert.fail("Unsupported ABI: " + PRIMARY_ABI);
        }
        assertEquals(checksums[1].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
    }

    @LargeTest
    @Test
    public void testFixedFSVerityDefaultChecksumsIncremental() throws Exception {
        if (!checkIncrementalDeliveryFeature()) {
            return;
        }

        installFilesIncrementally(
                new String[]{TEST_FIXED_APK_FSVERITY, TEST_FIXED_APK_FSVERITY_FSVSIG});
        assertTrue(isAppInstalled(FIXED_FSVERITY_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_FSVERITY_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256);
        if ("x86_64".equals(PRIMARY_ABI) || "x86".equals(PRIMARY_ABI)) {
            assertEquals(bytesToHexString(checksums[0].getValue()),
                    TEST_FIXED_APK_FSVERITY_SHA256_X86_64);
        } else if ("arm64-v8a".equals(PRIMARY_ABI) || "armeabi".equals(PRIMARY_ABI)
                || "armeabi-v7a".equals(PRIMARY_ABI)) {
            assertEquals(bytesToHexString(checksums[0].getValue()),
                    TEST_FIXED_APK_FSVERITY_SHA256_ARM64);
        } else {
            Assert.fail("Unsupported ABI: " + PRIMARY_ABI);
        }
    }

    @Test
    public void testFixedVerityDefaultChecksums() throws Exception {
        installPackage(TEST_FIXED_APK_VERITY);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        // No usable hashes as verity-in-v2-signature does not cover the whole file.
        assertEquals(checksums.length, 0);
    }

    @LargeTest
    @Test
    public void testFixedAllChecksums() throws Exception {
        installPackage(TEST_FIXED_APK);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, ALL_CHECKSUMS, TRUST_NONE,
                receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 7);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()),
                "759626c33083fbf43215cb5b17156977d963d4c6850c0cb4e73162a665db560b");
        assertEquals(checksums[1].getType(), TYPE_WHOLE_MD5);
        assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_MD5);
        assertEquals(checksums[2].getType(), TYPE_WHOLE_SHA1);
        assertEquals(bytesToHexString(checksums[2].getValue()),
                "331eef6bc57671de28cbd7e32089d047285ade6a");
        assertEquals(checksums[3].getType(), TYPE_WHOLE_SHA256);
        assertEquals(bytesToHexString(checksums[3].getValue()), TEST_FIXED_APK_SHA256);
        assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA512);
        assertEquals(bytesToHexString(checksums[4].getValue()),
                "b59467fe578ebc81974ab3aaa1e0d2a76fef3e4ea7212a6f2885cec1af5253571"
                        + "1e2e94496224cae3eba8dc992144ade321540ebd458ec5b9e6a4cc51170e018");
        assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[5].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertEquals(checksums[6].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512);
        assertEquals(bytesToHexString(checksums[6].getValue()),
                "ef80a8630283f60108e8557c924307d0ccdfb6bbbf2c0176bd49af342f43bc84"
                        + "5f2888afcb71524196dda0d6dd16a6a3292bb75b431b8ff74fb60d796e882f80");
    }

    @LargeTest
    @Test
    public void testFixedV1AllChecksums() throws Exception {
        installPackage(TEST_FIXED_APK_V1);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, ALL_CHECKSUMS, TRUST_NONE,
                receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 5);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()),
                "0b9bd6ef683e0c4e8940aba6460382b33e607c0fcf487f3dc6a44b715615d166");
        assertEquals(checksums[1].getType(), TYPE_WHOLE_MD5);
        assertEquals(bytesToHexString(checksums[1].getValue()), "78e51e8c51e4adc6870cd71389e0f3db");
        assertEquals(checksums[2].getType(), TYPE_WHOLE_SHA1);
        assertEquals(bytesToHexString(checksums[2].getValue()),
                "f6654505f2274fd9bfc098b660cdfdc2e4da6d53");
        assertEquals(checksums[3].getType(), TYPE_WHOLE_SHA256);
        assertEquals(bytesToHexString(checksums[3].getValue()),
                "43755d36ec944494f6275ee92662aca95079b3aa6639f2d35208c5af15adff78");
        assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA512);
        assertEquals(bytesToHexString(checksums[4].getValue()),
                "030fc815a4957c163af2bc6f30dd5b48ac09c94c25a824a514609e1476f91421"
                        + "e2c8b6baa16ef54014ad6c5b90c37b26b0f5c8aeb01b63a1db2eca133091c8d1");
    }

    @Test
    public void testDefaultIncrementalChecksums() throws Exception {
        if (!checkIncrementalDeliveryFeature()) {
            return;
        }
        installPackageIncrementally(TEST_V4_APK);
        assertTrue(isAppInstalled(V4_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256);
    }

    @Test
    public void testFixedDefaultIncrementalChecksums() throws Exception {
        if (!checkIncrementalDeliveryFeature()) {
            return;
        }
        installPackageIncrementally(TEST_FIXED_APK);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()),
                "759626c33083fbf43215cb5b17156977d963d4c6850c0cb4e73162a665db560b");
    }

    @LargeTest
    @Test
    public void testFixedAllIncrementalChecksums() throws Exception {
        if (!checkIncrementalDeliveryFeature()) {
            return;
        }
        installPackageIncrementally(TEST_FIXED_APK);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, ALL_CHECKSUMS, TRUST_NONE,
                receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 7);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MERKLE_ROOT_4K_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()),
                "759626c33083fbf43215cb5b17156977d963d4c6850c0cb4e73162a665db560b");
        assertEquals(checksums[1].getType(), TYPE_WHOLE_MD5);
        assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_MD5);
        assertEquals(checksums[2].getType(), TYPE_WHOLE_SHA1);
        assertEquals(bytesToHexString(checksums[2].getValue()),
                "331eef6bc57671de28cbd7e32089d047285ade6a");
        assertEquals(checksums[3].getType(), TYPE_WHOLE_SHA256);
        assertEquals(bytesToHexString(checksums[3].getValue()), TEST_FIXED_APK_SHA256);
        assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA512);
        assertEquals(bytesToHexString(checksums[4].getValue()),
                "b59467fe578ebc81974ab3aaa1e0d2a76fef3e4ea7212a6f2885cec1af5253571"
                        + "1e2e94496224cae3eba8dc992144ade321540ebd458ec5b9e6a4cc51170e018");
        assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[5].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertEquals(checksums[6].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512);
        assertEquals(bytesToHexString(checksums[6].getValue()),
                "ef80a8630283f60108e8557c924307d0ccdfb6bbbf2c0176bd49af342f43bc84"
                        + "5f2888afcb71524196dda0d6dd16a6a3292bb75b431b8ff74fb60d796e882f80");
    }


    @Test
    public void testInstallerChecksumsTrustNone() throws Exception {
        installApkWithChecksums(TEST_FIXED_APK_DIGESTS);

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertNull(checksums[0].getInstallerPackageName());
        assertNull(checksums[0].getInstallerCertificate());
    }

    @Test
    public void testInstallerWrongChecksumsTrustAll() throws Exception {
        installApkWithChecksums(TEST_FIXED_APK_WRONG_DIGESTS);

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertNull(checksums[0].getInstallerPackageName());
        assertNull(checksums[0].getInstallerCertificate());
    }

    @Test
    public void testInstallerSignedChecksumsInvalidSignature() throws Exception {
        getUiAutomation().adoptShellPermissionIdentity();
        try {
            final PackageInstaller installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
            params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;

            final int sessionId = installer.createSession(params);
            Session session = installer.openSession(sessionId);
            writeFileToSession(session, "file", TEST_FIXED_APK);
            try {
                session.setChecksums("file", Arrays.asList(TEST_FIXED_APK_DIGESTS),
                        hexStringToBytes("1eec9e86"));
                Assert.fail("setChecksums should throw exception.");
            } catch (IllegalArgumentException e) {
                // expected
            }
        } finally {
            getUiAutomation().dropShellPermissionIdentity();
        }
    }

    @Test
    public void testInstallerSignedChecksumsTrustNone() throws Exception {
        final byte[] signature = readSignature();

        CommitIntentReceiver.checkSuccess(
                installApkWithChecksums(TEST_FIXED_APK, "file", "file", TEST_FIXED_APK_DIGESTS,
                        signature));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertNull(checksums[0].getInstallerPackageName());
        assertNull(checksums[0].getInstallerCertificate());
    }

    @Test
    public void testInstallerSignedChecksumsTrustAll() throws Exception {
        final byte[] signature = readSignature();
        final Certificate certificate = readCertificate();

        CommitIntentReceiver.checkSuccess(
                installApkWithChecksums(TEST_FIXED_APK, "file", "file", TEST_FIXED_APK_DIGESTS,
                        signature));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        // v2/v3+installer provided.
        assertEquals(checksums.length, 3);

        assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5);
        assertEquals(checksums[0].getSplitName(), null);
        assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[0].getInstallerCertificate(), certificate);
        assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
        assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256);
        assertEquals(checksums[1].getSplitName(), null);
        assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[1].getInstallerCertificate(), certificate);
        assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertEquals(checksums[2].getSplitName(), null);
        assertNull(checksums[2].getInstallerPackageName());
        assertNull(checksums[2].getInstallerCertificate());
    }

    @Test
    public void testInstallerChecksumsTrustAll() throws Exception {
        installApkWithChecksums(TEST_FIXED_APK_DIGESTS);

        final Certificate installerCertificate = getInstallerCertificate();

        LocalListener receiver = new LocalListener();
        getPackageManager().requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL,
                receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        // v2/v3+installer provided.
        assertEquals(checksums.length, 3);

        assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5);
        assertEquals(checksums[0].getSplitName(), null);
        assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[0].getInstallerCertificate(), installerCertificate);
        assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
        assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256);
        assertEquals(checksums[1].getSplitName(), null);
        assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[1].getInstallerCertificate(), installerCertificate);
        assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertEquals(checksums[2].getSplitName(), null);
        assertNull(checksums[2].getInstallerPackageName());
        assertNull(checksums[2].getInstallerCertificate());
    }

    @Test
    public void testInstallerChecksumsTrustInstaller() throws Exception {
        installApkWithChecksums(TEST_FIXED_APK_DIGESTS);

        // Using the installer's certificate(s).
        PackageManager pm = getPackageManager();
        PackageInfo packageInfo = pm.getPackageInfo(CTS_PACKAGE_NAME,
                PackageManager.PackageInfoFlags.of(GET_SIGNING_CERTIFICATES));
        final List<Certificate> signatures = convertSignaturesToCertificates(
                packageInfo.signingInfo.getApkContentsSigners());

        LocalListener receiver = new LocalListener();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, signatures, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 3);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5);
        assertEquals(checksums[0].getSplitName(), null);
        assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[0].getInstallerCertificate(), signatures.get(0));
        assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
        assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256);
        assertEquals(checksums[1].getSplitName(), null);
        assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[1].getInstallerCertificate(), signatures.get(0));
        assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertEquals(checksums[2].getSplitName(), null);
        assertNull(checksums[2].getInstallerPackageName());
        assertNull(checksums[2].getInstallerCertificate());
    }

    @LargeTest
    @Test
    public void testInstallerFileChecksumsDuringInstall() throws Exception {
        Checksum[] digestsBase = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(
                "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e")),
                new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("dd93e23bb8cdab0382fdca0d21a4f1cb"))};
        Checksum[] digestsSplit0 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(
                "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e")),
                new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("f6430e1b795ce2658c49e68d15316b2d"))};

        final Certificate installerCertificate = getInstallerCertificate();

        getUiAutomation().adoptShellPermissionIdentity();
        PackageInstaller installer = null;
        int sessionId = -1;
        try {
            installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
            params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;

            sessionId = installer.createSession(params);
            final Session session = installer.openSession(sessionId);

            writeFileToSession(session, "hw5.apk", TEST_V4_APK);
            session.setChecksums("hw5.apk", Arrays.asList(digestsBase), NO_SIGNATURE);

            writeFileToSession(session, "hw5_split0.apk", TEST_V4_SPLIT0);
            session.setChecksums("hw5_split0.apk", Arrays.asList(digestsSplit0), NO_SIGNATURE);

            // Workaround to emulate .digests file present in installation.
            writeChecksumsToSession(session, "hw5.digests", digestsBase);
            writeChecksumsToSession(session, "hw5_split0.digests", digestsSplit0);

            File dataApp = Environment.getDataAppDirectory(null);

            {
                LocalListener receiver = new LocalListener();

                session.requestChecksums("hw5.apk", 0, TRUST_ALL, getContext().getMainExecutor(),
                        receiver);
                ApkChecksum[] checksums = receiver.getResult();
                assertNotNull(checksums);
                assertEquals(checksums.length, 3);
                // base
                assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
                assertEquals(checksums[0].getSplitName(), null);
                assertEquals(bytesToHexString(checksums[0].getValue()),
                        "dd93e23bb8cdab0382fdca0d21a4f1cb");
                assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
                assertEquals(checksums[0].getInstallerCertificate(), installerCertificate);
                assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
                assertEquals(checksums[1].getSplitName(), null);
                assertEquals(bytesToHexString(checksums[1].getValue()),
                        "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e");
                assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
                assertEquals(checksums[1].getInstallerCertificate(), installerCertificate);
                assertEquals(checksums[2].getSplitName(), null);
                assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
                assertNull(checksums[2].getInstallerPackageName());
                assertNull(checksums[2].getInstallerCertificate());
            }
            {
                LocalListener receiver = new LocalListener();

                session.requestChecksums("hw5_split0.apk", 0, TRUST_ALL,
                        getContext().getMainExecutor(), receiver);
                ApkChecksum[] checksums = receiver.getResult();
                assertNotNull(checksums);
                assertEquals(checksums.length, 3);
                // split0
                assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
                assertEquals(checksums[0].getSplitName(), null);
                assertEquals(bytesToHexString(checksums[0].getValue()),
                        "f6430e1b795ce2658c49e68d15316b2d");
                assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
                assertEquals(checksums[0].getInstallerCertificate(), installerCertificate);
                assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
                assertEquals(checksums[1].getSplitName(), null);
                assertEquals(bytesToHexString(checksums[1].getValue()),
                        "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e");
                assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
                assertEquals(checksums[1].getInstallerCertificate(), installerCertificate);
                assertEquals(checksums[2].getSplitName(), null);
                assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
                assertNull(checksums[2].getInstallerPackageName());
                assertNull(checksums[2].getInstallerCertificate());
            }
        } finally {
            installer.abandonSession(sessionId);
            getUiAutomation().dropShellPermissionIdentity();
        }
    }

    @Test
    public void testInstallerChecksumsTrustWrongInstaller() throws Exception {
        installApkWithChecksums(TEST_FIXED_APK_DIGESTS);

        // Using certificates from a security app, not the installer (us).
        PackageManager pm = getPackageManager();
        PackageInfo packageInfo = pm.getPackageInfo(FIXED_PACKAGE_NAME,
                PackageManager.PackageInfoFlags.of(GET_SIGNING_CERTIFICATES));
        final List<Certificate> signatures = convertSignaturesToCertificates(
                packageInfo.signingInfo.getApkContentsSigners());

        LocalListener receiver = new LocalListener();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, signatures, receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertNull(checksums[0].getInstallerPackageName());
        assertNull(checksums[0].getInstallerCertificate());
    }

    @Test
    public void testInstallerChecksumsTrustAllWrongName() throws Exception {
        // NB: "Invalid checksum name(s):" is used in Play to report checksum related failures.
        // Please consult with them before changing.
        CommitIntentReceiver.checkFailure(
                installApkWithChecksums(TEST_FIXED_APK, "apk", "wrong_name",
                        TEST_FIXED_APK_DIGESTS),
                "INSTALL_FAILED_SESSION_INVALID: Invalid checksum name(s): wrong_name");
    }

    @Test
    public void testInstallerChecksumsUpdate() throws Exception {
        Checksum[] digestsBase = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(
                "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e")),
                new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("dd93e23bb8cdab0382fdca0d21a4f1cb"))};
        Checksum[] digestsSplit0 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(
                "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e")),
                new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("f6430e1b795ce2658c49e68d15316b2d"))};
        Checksum[] digestsSplit1 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(
                "f16898f43990c14585a900eda345c3a236c6224f63920d69cfe8a7afbc0c0ccf")),
                new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("d1f4b00d034994663e84f907fe4bb664"))};

        final Certificate installerCertificate = getInstallerCertificate();

        // Original package checksums: base + split0.
        getUiAutomation().adoptShellPermissionIdentity();
        try {
            final PackageInstaller installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);

            final int sessionId = installer.createSession(params);
            Session session = installer.openSession(sessionId);

            writeFileToSession(session, "hw5", TEST_V4_APK);
            session.setChecksums("hw5", Arrays.asList(digestsBase), NO_SIGNATURE);

            writeFileToSession(session, "hw5_split0", TEST_V4_SPLIT0);
            session.setChecksums("hw5_split0", Arrays.asList(digestsSplit0), NO_SIGNATURE);

            CommitIntentReceiver receiver = new CommitIntentReceiver();
            session.commit(receiver.getIntentSender());
            CommitIntentReceiver.checkSuccess(receiver.getResult());
        } finally {
            getUiAutomation().dropShellPermissionIdentity();
        }

        {
            LocalListener receiver = new LocalListener();
            PackageManager pm = getPackageManager();
            pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_ALL, receiver);
            ApkChecksum[] checksums = receiver.getResult();
            assertNotNull(checksums);
            assertEquals(checksums.length, 6);
            // base
            assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[0].getSplitName(), null);
            assertEquals(bytesToHexString(checksums[0].getValue()),
                    "dd93e23bb8cdab0382fdca0d21a4f1cb");
            assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[0].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[1].getSplitName(), null);
            assertEquals(bytesToHexString(checksums[1].getValue()),
                    "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e");
            assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[1].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[2].getSplitName(), null);
            assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[2].getInstallerPackageName());
            assertNull(checksums[2].getInstallerCertificate());
            // split0
            assertEquals(checksums[3].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[3].getSplitName(), "config.hdpi");
            assertEquals(bytesToHexString(checksums[3].getValue()),
                    "f6430e1b795ce2658c49e68d15316b2d");
            assertEquals(checksums[3].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[3].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[4].getSplitName(), "config.hdpi");
            assertEquals(bytesToHexString(checksums[4].getValue()),
                    "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e");
            assertEquals(checksums[4].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[4].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[5].getSplitName(), "config.hdpi");
            assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[5].getInstallerPackageName());
            assertNull(checksums[5].getInstallerCertificate());
        }

        // Update the package with one split+checksums and another split without checksums.
        getUiAutomation().adoptShellPermissionIdentity();
        try {
            final PackageInstaller installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
            params.setAppPackageName(V4_PACKAGE_NAME);

            final int sessionId = installer.createSession(params);
            Session session = installer.openSession(sessionId);

            writeFileToSession(session, "hw5_split1", TEST_V4_SPLIT1);
            session.setChecksums("hw5_split1", Arrays.asList(digestsSplit1), NO_SIGNATURE);

            writeFileToSession(session, "hw5_split2", TEST_V4_SPLIT2);

            CommitIntentReceiver receiver = new CommitIntentReceiver();
            session.commit(receiver.getIntentSender());
            CommitIntentReceiver.checkSuccess(receiver.getResult());
        } finally {
            getUiAutomation().dropShellPermissionIdentity();
        }

        {
            LocalListener receiver = new LocalListener();
            PackageManager pm = getPackageManager();
            pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_ALL, receiver);
            ApkChecksum[] checksums = receiver.getResult();
            assertNotNull(checksums);
            assertEquals(checksums.length, 10);
            // base
            assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[0].getSplitName(), null);
            assertEquals(bytesToHexString(checksums[0].getValue()),
                    "dd93e23bb8cdab0382fdca0d21a4f1cb");
            assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[0].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[1].getSplitName(), null);
            assertEquals(bytesToHexString(checksums[1].getValue()),
                    "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e");
            assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[1].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[2].getSplitName(), null);
            assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[2].getInstallerPackageName());
            assertNull(checksums[2].getInstallerCertificate());
            // split0
            assertEquals(checksums[3].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[3].getSplitName(), "config.hdpi");
            assertEquals(bytesToHexString(checksums[3].getValue()),
                    "f6430e1b795ce2658c49e68d15316b2d");
            assertEquals(checksums[3].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[3].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[4].getSplitName(), "config.hdpi");
            assertEquals(bytesToHexString(checksums[4].getValue()),
                    "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e");
            assertEquals(checksums[4].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[4].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[5].getSplitName(), "config.hdpi");
            assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[5].getInstallerPackageName());
            assertNull(checksums[5].getInstallerCertificate());
            // split1
            assertEquals(checksums[6].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[6].getSplitName(), "config.mdpi");
            assertEquals(bytesToHexString(checksums[6].getValue()),
                    "d1f4b00d034994663e84f907fe4bb664");
            assertEquals(checksums[6].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[6].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[7].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[7].getSplitName(), "config.mdpi");
            assertEquals(bytesToHexString(checksums[7].getValue()),
                    "f16898f43990c14585a900eda345c3a236c6224f63920d69cfe8a7afbc0c0ccf");
            assertEquals(checksums[7].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[7].getInstallerCertificate(), installerCertificate);
            assertEquals(checksums[8].getSplitName(), "config.mdpi");
            assertEquals(checksums[8].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[8].getInstallerPackageName());
            assertNull(checksums[8].getInstallerCertificate());
            // split2
            assertEquals(checksums[9].getSplitName(), "config.xhdpi");
            assertEquals(checksums[9].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[9].getInstallerPackageName());
            assertNull(checksums[9].getInstallerCertificate());
        }
    }

    @Test
    public void testInstallerSignedChecksumsUpdate() throws Exception {
        Checksum[] digestsBase = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(
                "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e")),
                new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("dd93e23bb8cdab0382fdca0d21a4f1cb"))};
        Checksum[] digestsSplit0 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(
                "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e")),
                new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("f6430e1b795ce2658c49e68d15316b2d"))};
        Checksum[] digestsSplit1 = new Checksum[]{new Checksum(TYPE_WHOLE_SHA256, hexStringToBytes(
                "f16898f43990c14585a900eda345c3a236c6224f63920d69cfe8a7afbc0c0ccf")),
                new Checksum(TYPE_WHOLE_MD5, hexStringToBytes("d1f4b00d034994663e84f907fe4bb664"))};

        String digestBaseFile = ApkChecksums.buildDigestsPathForApk(TEST_V4_APK);
        String digestSplit0File = ApkChecksums.buildDigestsPathForApk(TEST_V4_SPLIT0);
        String digestSplit1File = ApkChecksums.buildDigestsPathForApk(TEST_V4_SPLIT1);

        checkStoredChecksums(digestsBase, digestBaseFile);
        checkStoredChecksums(digestsSplit0, digestSplit0File);
        checkStoredChecksums(digestsSplit1, digestSplit1File);

        byte[] digestBaseSignature = readSignature(
                ApkChecksums.buildSignaturePathForDigests(digestBaseFile));
        byte[] digestSplit0Signature = readSignature(
                ApkChecksums.buildSignaturePathForDigests(digestSplit0File));
        byte[] digestSplit1Signature = readSignature(
                ApkChecksums.buildSignaturePathForDigests(digestSplit1File));

        final Certificate certificate = readCertificate();

        // Original package checksums: base + split0.
        getUiAutomation().adoptShellPermissionIdentity();
        try {
            final PackageInstaller installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);

            final int sessionId = installer.createSession(params);
            Session session = installer.openSession(sessionId);

            writeFileToSession(session, "hw5", TEST_V4_APK);
            session.setChecksums("hw5", Arrays.asList(digestsBase), digestBaseSignature);

            writeFileToSession(session, "hw5_split0", TEST_V4_SPLIT0);
            session.setChecksums("hw5_split0", Arrays.asList(digestsSplit0), digestSplit0Signature);

            CommitIntentReceiver receiver = new CommitIntentReceiver();
            session.commit(receiver.getIntentSender());
            CommitIntentReceiver.checkSuccess(receiver.getResult());
        } finally {
            getUiAutomation().dropShellPermissionIdentity();
        }

        {
            LocalListener receiver = new LocalListener();
            PackageManager pm = getPackageManager();
            pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_ALL, receiver);
            ApkChecksum[] checksums = receiver.getResult();
            assertNotNull(checksums);
            assertEquals(checksums.length, 6);
            // base
            assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[0].getSplitName(), null);
            assertEquals(bytesToHexString(checksums[0].getValue()),
                    "dd93e23bb8cdab0382fdca0d21a4f1cb");
            assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[0].getInstallerCertificate(), certificate);
            assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[1].getSplitName(), null);
            assertEquals(bytesToHexString(checksums[1].getValue()),
                    "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e");
            assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[1].getInstallerCertificate(), certificate);
            assertEquals(checksums[2].getSplitName(), null);
            assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[2].getInstallerPackageName());
            assertNull(checksums[2].getInstallerCertificate());
            // split0
            assertEquals(checksums[3].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[3].getSplitName(), "config.hdpi");
            assertEquals(bytesToHexString(checksums[3].getValue()),
                    "f6430e1b795ce2658c49e68d15316b2d");
            assertEquals(checksums[3].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[3].getInstallerCertificate(), certificate);
            assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[4].getSplitName(), "config.hdpi");
            assertEquals(bytesToHexString(checksums[4].getValue()),
                    "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e");
            assertEquals(checksums[4].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[4].getInstallerCertificate(), certificate);
            assertEquals(checksums[5].getSplitName(), "config.hdpi");
            assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[5].getInstallerPackageName());
            assertNull(checksums[5].getInstallerCertificate());
        }

        // Update the package with one split+checksums and another split without checksums.
        getUiAutomation().adoptShellPermissionIdentity();
        try {
            final PackageInstaller installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
            params.setAppPackageName(V4_PACKAGE_NAME);

            final int sessionId = installer.createSession(params);
            Session session = installer.openSession(sessionId);

            writeFileToSession(session, "hw5_split1", TEST_V4_SPLIT1);
            session.setChecksums("hw5_split1", Arrays.asList(digestsSplit1), digestSplit1Signature);

            writeFileToSession(session, "hw5_split2", TEST_V4_SPLIT2);

            CommitIntentReceiver receiver = new CommitIntentReceiver();
            session.commit(receiver.getIntentSender());
            CommitIntentReceiver.checkSuccess(receiver.getResult());
        } finally {
            getUiAutomation().dropShellPermissionIdentity();
        }

        {
            LocalListener receiver = new LocalListener();
            PackageManager pm = getPackageManager();
            pm.requestChecksums(V4_PACKAGE_NAME, true, 0, TRUST_ALL, receiver);
            ApkChecksum[] checksums = receiver.getResult();
            assertNotNull(checksums);
            assertEquals(checksums.length, 10);
            // base
            assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[0].getSplitName(), null);
            assertEquals(bytesToHexString(checksums[0].getValue()),
                    "dd93e23bb8cdab0382fdca0d21a4f1cb");
            assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[0].getInstallerCertificate(), certificate);
            assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[1].getSplitName(), null);
            assertEquals(bytesToHexString(checksums[1].getValue()),
                    "ed8c7ae1220fe16d558e00cfc37256e6f7088ab90eb04c1bfcb39922a8a5248e");
            assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[1].getInstallerCertificate(), certificate);
            assertEquals(checksums[2].getSplitName(), null);
            assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[2].getInstallerPackageName());
            assertNull(checksums[2].getInstallerCertificate());
            // split0
            assertEquals(checksums[3].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[3].getSplitName(), "config.hdpi");
            assertEquals(bytesToHexString(checksums[3].getValue()),
                    "f6430e1b795ce2658c49e68d15316b2d");
            assertEquals(checksums[3].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[3].getInstallerCertificate(), certificate);
            assertEquals(checksums[4].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[4].getSplitName(), "config.hdpi");
            assertEquals(bytesToHexString(checksums[4].getValue()),
                    "bd9b095a49a9068498b018ce8cb7cc18d411b13a5a5f7fb417d2ff9808ae838e");
            assertEquals(checksums[4].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[4].getInstallerCertificate(), certificate);
            assertEquals(checksums[5].getSplitName(), "config.hdpi");
            assertEquals(checksums[5].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[5].getInstallerPackageName());
            assertNull(checksums[5].getInstallerCertificate());
            // split1
            assertEquals(checksums[6].getType(), TYPE_WHOLE_MD5);
            assertEquals(checksums[6].getSplitName(), "config.mdpi");
            assertEquals(bytesToHexString(checksums[6].getValue()),
                    "d1f4b00d034994663e84f907fe4bb664");
            assertEquals(checksums[6].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[6].getInstallerCertificate(), certificate);
            assertEquals(checksums[7].getType(), TYPE_WHOLE_SHA256);
            assertEquals(checksums[7].getSplitName(), "config.mdpi");
            assertEquals(bytesToHexString(checksums[7].getValue()),
                    "f16898f43990c14585a900eda345c3a236c6224f63920d69cfe8a7afbc0c0ccf");
            assertEquals(checksums[7].getInstallerPackageName(), CTS_PACKAGE_NAME);
            assertEquals(checksums[7].getInstallerCertificate(), certificate);
            assertEquals(checksums[8].getSplitName(), "config.mdpi");
            assertEquals(checksums[8].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[8].getInstallerPackageName());
            assertNull(checksums[8].getInstallerCertificate());
            // split2
            assertEquals(checksums[9].getSplitName(), "config.xhdpi");
            assertEquals(checksums[9].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
            assertNull(checksums[9].getInstallerPackageName());
            assertNull(checksums[9].getInstallerCertificate());
        }
    }

    @Test
    public void testInstallerChecksumsIncremental() throws Exception {
        if (!checkIncrementalDeliveryFeature()) {
            return;
        }

        final Certificate installerCertificate = getInstallerCertificate();

        installPackageIncrementally(TEST_FIXED_APK);

        PackageManager pm = getPackageManager();
        PackageInfo packageInfo = pm.getPackageInfo(FIXED_PACKAGE_NAME,
                PackageManager.PackageInfoFlags.of(0));
        final String inPath = packageInfo.applicationInfo.getBaseCodePath();

        installApkWithChecksumsIncrementally(inPath);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL,
                receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 3);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5);
        assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[0].getInstallerCertificate(), installerCertificate);
        assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
        assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256);
        assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[1].getInstallerCertificate(), installerCertificate);
        assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertNull(checksums[2].getInstallerPackageName());
        assertNull(checksums[2].getInstallerCertificate());
    }

    @Test
    public void testInstallerSignedChecksumsIncremental() throws Exception {
        if (!checkIncrementalDeliveryFeature()) {
            return;
        }

        installPackageIncrementally(TEST_FIXED_APK);

        PackageInfo packageInfo = getPackageManager().getPackageInfo(FIXED_PACKAGE_NAME,
                PackageManager.PackageInfoFlags.of(0));
        final String inPath = packageInfo.applicationInfo.getBaseCodePath();

        final byte[] signature = readSignature();
        final Certificate certificate = readCertificate();

        installApkWithChecksumsIncrementally(inPath, TEST_FIXED_APK, TEST_FIXED_APK_DIGESTS,
                signature);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_ALL,
                receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 3);
        assertEquals(checksums[0].getType(), TYPE_WHOLE_MD5);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_MD5);
        assertEquals(checksums[0].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[0].getInstallerCertificate(), certificate);
        assertEquals(checksums[1].getType(), TYPE_WHOLE_SHA256);
        assertEquals(bytesToHexString(checksums[1].getValue()), TEST_FIXED_APK_SHA256);
        assertEquals(checksums[1].getInstallerPackageName(), CTS_PACKAGE_NAME);
        assertEquals(checksums[1].getInstallerCertificate(), certificate);
        assertEquals(checksums[2].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[2].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertNull(checksums[2].getInstallerPackageName());
        assertNull(checksums[2].getInstallerCertificate());
    }

    @Test
    public void testInstallerChecksumsIncrementalTrustNone() throws Exception {
        if (!checkIncrementalDeliveryFeature()) {
            return;
        }

        installPackageIncrementally(TEST_FIXED_APK);

        PackageInfo packageInfo = getPackageManager().getPackageInfo(FIXED_PACKAGE_NAME,
                PackageManager.PackageInfoFlags.of(0));
        final String inPath = packageInfo.applicationInfo.getBaseCodePath();

        installApkWithChecksumsIncrementally(inPath);
        assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));

        LocalListener receiver = new LocalListener();
        PackageManager pm = getPackageManager();
        pm.requestChecksums(FIXED_PACKAGE_NAME, true, 0, TRUST_NONE,
                receiver);
        ApkChecksum[] checksums = receiver.getResult();
        assertNotNull(checksums);
        assertEquals(checksums.length, 1);
        assertEquals(checksums[0].getType(), TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256);
        assertEquals(bytesToHexString(checksums[0].getValue()), TEST_FIXED_APK_V2_SHA256);
        assertNull(checksums[0].getInstallerPackageName());
        assertNull(checksums[0].getInstallerCertificate());
    }

    @Test
    public void testInstallerChecksumsDuplicate() throws Exception {
        getUiAutomation().adoptShellPermissionIdentity();
        try {
            final PackageInstaller installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);

            final int sessionId = installer.createSession(params);
            Session session = installer.openSession(sessionId);
            writeFileToSession(session, "file", TEST_FIXED_APK);
            session.setChecksums("file", Arrays.asList(TEST_FIXED_APK_DIGESTS), NO_SIGNATURE);
            try {
                session.setChecksums("file", Arrays.asList(TEST_FIXED_APK_DIGESTS), NO_SIGNATURE);
                Assert.fail("setChecksums should throw exception.");
            } catch (IllegalStateException e) {
                // expected
            }
        } finally {
            getUiAutomation().dropShellPermissionIdentity();
        }
    }

    private List<Certificate> convertSignaturesToCertificates(Signature[] signatures) {
        try {
            final CertificateFactory cf = CertificateFactory.getInstance("X.509");
            ArrayList<Certificate> certs = new ArrayList<>(signatures.length);
            for (Signature signature : signatures) {
                final InputStream is = new ByteArrayInputStream(signature.toByteArray());
                final X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
                certs.add(cert);
            }
            return certs;
        } catch (CertificateException e) {
            throw ExceptionUtils.propagate(e);
        }
    }

    private void installApkWithChecksums(Checksum[] checksums) throws Exception {
        installApkWithChecksums("file", "file", checksums);
    }

    private void installApkWithChecksums(String apkName, String checksumsName, Checksum[] checksums)
            throws Exception {
        CommitIntentReceiver.checkSuccess(
                installApkWithChecksums(TEST_FIXED_APK, apkName, checksumsName, checksums));
    }

    private Intent installApkWithChecksums(String apk, String apkName,
            String checksumsName, Checksum[] checksums) throws Exception {
        return installApkWithChecksums(apk, apkName, checksumsName, checksums, NO_SIGNATURE);
    }

    private Intent installApkWithChecksums(String apk, String apkName,
            String checksumsName, Checksum[] checksums, byte[] signature) throws Exception {
        getUiAutomation().adoptShellPermissionIdentity();
        try {
            final PackageInstaller installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);

            final int sessionId = installer.createSession(params);
            Session session = installer.openSession(sessionId);
            writeFileToSession(session, apkName, apk);
            session.setChecksums(checksumsName, Arrays.asList(checksums), signature);

            CommitIntentReceiver receiver = new CommitIntentReceiver();
            session.commit(receiver.getIntentSender());
            return receiver.getResult();
        } finally {
            getUiAutomation().dropShellPermissionIdentity();
        }
    }

    private void installApkWithFSVerity(String apk, String fsv) throws Exception {
        getUiAutomation().adoptShellPermissionIdentity();
        try {
            final PackageInstaller installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);

            final int sessionId = installer.createSession(params);
            Session session = installer.openSession(sessionId);
            writeFileToSession(session, "file", apk);
            writeFileToSession(session, "file.fsv_sig", fsv);

            CommitIntentReceiver receiver = new CommitIntentReceiver();
            session.commit(receiver.getIntentSender());
            CommitIntentReceiver.checkSuccess(receiver.getResult());
        } finally {
            getUiAutomation().dropShellPermissionIdentity();
        }
    }
    private void installApkWithChecksumsIncrementally(final String inPath) throws Exception {
        installApkWithChecksumsIncrementally(inPath, TEST_FIXED_APK, TEST_FIXED_APK_DIGESTS,
                NO_SIGNATURE);
    }

    private void installApkWithChecksumsIncrementally(final String inPath, final String apk,
            final Checksum[] checksums, final byte[] signature) throws Exception {
        getUiAutomation().adoptShellPermissionIdentity();
        try {
            final PackageInstaller installer = getPackageInstaller();
            final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
            params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
            params.setDataLoaderParams(DataLoaderParams.forIncremental(new ComponentName("android",
                    PackageManagerShellCommandDataLoader.class.getName()), ""));

            final int sessionId = installer.createSession(params);
            Session session = installer.openSession(sessionId);

            final File file = new File(inPath);
            final String name = file.getName();
            final long size = file.length();
            final Metadata metadata = Metadata.forLocalFile(inPath);

            session.addFile(LOCATION_DATA_APP, name, size, metadata.toByteArray(), null);
            session.setChecksums(name, Arrays.asList(checksums), signature);

            CommitIntentReceiver receiver = new CommitIntentReceiver();
            session.commit(receiver.getIntentSender());
            CommitIntentReceiver.checkSuccess(receiver.getResult());
        } finally {
            getUiAutomation().dropShellPermissionIdentity();
        }
    }

    private static String readFullStream(InputStream inputStream) throws IOException {
        ByteArrayOutputStream result = new ByteArrayOutputStream();
        writeFullStream(inputStream, result, -1);
        return result.toString("UTF-8");
    }

    private static void writeFullStream(InputStream inputStream, OutputStream outputStream,
            long expected)
            throws IOException {
        byte[] buffer = new byte[1024];
        long total = 0;
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
            total += length;
        }
        if (expected > 0) {
            Assert.assertEquals(expected, total);
        }
    }

    private static String executeShellCommand(String command) throws IOException {
        final ParcelFileDescriptor stdout = getUiAutomation().executeShellCommand(command);
        try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(stdout)) {
            return readFullStream(inputStream);
        }
    }

    private static String createApkPath(String baseName) {
        return TEST_APK_PATH + baseName;
    }

    private void installPackage(String baseName) throws IOException {
        File file = new File(createApkPath(baseName));
        Assert.assertEquals("Success\n", executeShellCommand(
                "pm install -t -g " + file.getPath()));
    }

    private void installPackageIncrementally(String baseName) throws IOException {
        File file = new File(createApkPath(baseName));
        Assert.assertEquals("Success\n", executeShellCommand(
                "pm install-incremental -t -g " + file.getPath()));
    }

    private void installSplits(String[] baseNames) throws IOException {
        String[] splits = Arrays.stream(baseNames).map(
                baseName -> createApkPath(baseName)).toArray(String[]::new);
        Assert.assertEquals("Success\n",
                executeShellCommand("pm install -t -g " + String.join(" ", splits)));
    }

    private void installFilesIncrementally(String[] baseNames) throws IOException {
        String[] splits = Arrays.stream(baseNames).map(
                baseName -> createApkPath(baseName)).toArray(String[]::new);
        Assert.assertEquals("Success\n",
                executeShellCommand("pm install-incremental -t -g " + String.join(" ", splits)));
    }

    private static void writeFileToSession(PackageInstaller.Session session, String name,
            String apk) throws IOException {
        File file = new File(createApkPath(apk));
        try (OutputStream os = session.openWrite(name, 0, file.length());
             InputStream is = new FileInputStream(file)) {
            writeFullStream(is, os, file.length());
        }
    }

    private static void writeChecksumsToSession(PackageInstaller.Session session, String name,
            Checksum[] checksums) throws IOException {
        try (DataOutputStream dos = new DataOutputStream(session.openWrite(name, 0, -1))) {
            for (Checksum checksum : checksums) {
                Checksum.writeToStream(dos, checksum);
            }
        }
    }

    private String uninstallPackageSilently(String packageName) throws IOException {
        return executeShellCommand("pm uninstall " + packageName);
    }

    private boolean isAppInstalled(String packageName) throws IOException {
        final String commandResult = executeShellCommand("pm list packages");
        final int prefixLength = "package:".length();
        return Arrays.stream(commandResult.split("\\r?\\n"))
                .anyMatch(line -> line.substring(prefixLength).equals(packageName));
    }

    private String getAppCodePath(String packageName) throws IOException {
        final String commandResult = executeShellCommand("pm dump " + packageName);
        final String prefix = "    codePath=";
        final int prefixLength = prefix.length();
        return Arrays.stream(commandResult.split("\\r?\\n"))
                .filter(line -> line.startsWith(prefix))
                .map(line -> line.substring(prefixLength))
                .findFirst().get();
    }

    @Nonnull
    private static String bytesToHexString(byte[] bytes) {
        return HexDump.toHexString(bytes, 0, bytes.length, /*upperCase=*/ false);
    }

    @Nonnull
    private static byte[] hexStringToBytes(String hexString) {
        return HexDump.hexStringToByteArray(hexString);
    }

    private boolean checkIncrementalDeliveryFeature() {
        return getPackageManager().hasSystemFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY);
    }

    // From PackageManagerServiceUtils.
    private static boolean isApkVerityEnabled() {
        return Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.R
                || SystemProperties.getInt("ro.apk_verity.mode", FSVERITY_DISABLED)
                == FSVERITY_ENABLED;
    }

    private byte[] readSignature() throws IOException {
        return readSignature(TEST_FIXED_APK_DIGESTS_SIGNATURE);
    }

    private byte[] readSignature(String file) throws IOException {
        return Files.readAllBytes(Paths.get(createApkPath(file)));
    }

    private Certificate readCertificate() throws Exception {
        try (InputStream is = new FileInputStream(createApkPath(TEST_CERTIFICATE))) {
            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            return certFactory.generateCertificate(is);
        }
    }

    private Certificate getInstallerCertificate() throws Exception {
        PackageManager pm = getPackageManager();
        PackageInfo installerPackageInfo = pm.getPackageInfo(CTS_PACKAGE_NAME,
                PackageManager.PackageInfoFlags.of(GET_SIGNING_CERTIFICATES));
        final List<Certificate> signatures = convertSignaturesToCertificates(
                installerPackageInfo.signingInfo.getApkContentsSigners());
        return signatures.get(0);
    }

    private void checkStoredChecksums(Checksum[] checksums, String fileName) throws Exception {
        ArrayList<Checksum> storedChecksumsList = new ArrayList<>();
        try (InputStream is = new FileInputStream(createApkPath(fileName));
             DataInputStream dis = new DataInputStream(is)) {
            for (int i = 0; i < 100; ++i) {
                try {
                    storedChecksumsList.add(Checksum.readFromStream(dis));
                } catch (EOFException e) {
                    break;
                }
            }
        }
        final Checksum[] storedChecksums = storedChecksumsList.toArray(
                new Checksum[storedChecksumsList.size()]);

        final String message = fileName + " needs to be updated: ";
        Assert.assertEquals(message, storedChecksums.length, checksums.length);
        for (int i = 0, size = storedChecksums.length; i < size; ++i) {
            Assert.assertEquals(message, storedChecksums[i].getType(), checksums[i].getType());
            Assert.assertArrayEquals(message, storedChecksums[i].getValue(),
                    checksums[i].getValue());
        }
    }

    private static class LocalListener implements PackageManager.OnChecksumsReadyListener {
        private final LinkedBlockingQueue<ApkChecksum[]> mResult = new LinkedBlockingQueue<>();

        @Override
        public void onChecksumsReady(@NonNull List<ApkChecksum> checksumsList) {
            ApkChecksum[] checksums = checksumsList.toArray(new ApkChecksum[checksumsList.size()]);
            Arrays.sort(checksums, (ApkChecksum lhs, ApkChecksum rhs) ->  {
                final String lhsSplit = lhs.getSplitName();
                final String rhsSplit = rhs.getSplitName();
                if (Objects.equals(lhsSplit, rhsSplit)) {
                    return Integer.signum(lhs.getType() - rhs.getType());
                }
                if (lhsSplit == null) {
                    return -1;
                }
                if (rhsSplit == null) {
                    return +1;
                }
                return lhsSplit.compareTo(rhsSplit);
            });
            mResult.offer(checksums);
        }

        public ApkChecksum[] getResult() {
            try {
                return mResult.poll(6, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private static class CommitIntentReceiver {
        private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();

        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
            @Override
            public void send(int code, Intent intent, String resolvedType, IBinder allowlistToken,
                    IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
                try {
                    mResult.offer(intent, 5, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        };

        public IntentSender getIntentSender() {
            return new IntentSender((IIntentSender) mLocalSender);
        }

        public Intent getResult() {
            try {
                return mResult.take();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        public static void checkSuccess(Intent result) {
            final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
                    PackageInstaller.STATUS_FAILURE);
            assertEquals(status, PackageInstaller.STATUS_SUCCESS,
                    result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + " OR "
                            + result.getExtras().get(Intent.EXTRA_INTENT));
        }

        public static void checkFailure(Intent result, int expectedStatus,
                String expectedStatusMessage) {
            final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
                    PackageInstaller.STATUS_FAILURE);
            assertEquals(status, expectedStatus);
            assertEquals(result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE),
                    expectedStatusMessage);
        }

        public static void checkFailure(Intent result, String expectedStatusMessage) {
            checkFailure(result, PackageInstaller.STATUS_FAILURE, expectedStatusMessage);
        }
    }
}
