Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1580e1c3 authored by Alex Buynytskyy's avatar Alex Buynytskyy Committed by Android (Google) Code Review
Browse files

Merge "Signature streaming from local file, property to disable incremental."

parents 08b20c4b 8e9e6a32
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ import java.nio.file.Paths;
public final class IncrementalManager {
    private static final String TAG = "IncrementalManager";

    private static final String ALLOWED_PROPERTY = "incremental.allowed";

    public static final int CREATE_MODE_TEMPORARY_BIND =
            IIncrementalService.CREATE_MODE_TEMPORARY_BIND;
    public static final int CREATE_MODE_PERMANENT_BIND =
@@ -288,12 +290,20 @@ public final class IncrementalManager {
    }

    /**
     * Checks if Incremental is enabled
     * Checks if Incremental feature is enabled on this device.
     */
    public static boolean isEnabled() {
    public static boolean isFeatureEnabled() {
        return nativeIsEnabled();
    }

    /**
     * Checks if Incremental installations are allowed.
     * A developer can disable Incremental installations by setting the property.
     */
    public static boolean isAllowed() {
        return isFeatureEnabled() && android.os.SystemProperties.getBoolean(ALLOWED_PROPERTY, true);
    }

    /**
     * Checks if path is mounted on Incremental File System.
     */
+42 −11
Original line number Diff line number Diff line
@@ -16,8 +16,11 @@

package android.os.incremental;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
@@ -26,20 +29,36 @@ import java.io.IOException;
 * @hide
 */
public class V4Signature {
    public static final String EXT = ".idsig";

    public final byte[] verityRootHash;
    public final byte[] v3Digest;
    public final byte[] pkcs7SignatureBlock;

    V4Signature(byte[] verityRootHash, byte[] v3Digest, byte[] pkcs7SignatureBlock) {
        this.verityRootHash = verityRootHash;
        this.v3Digest = v3Digest;
        this.pkcs7SignatureBlock = pkcs7SignatureBlock;
    /**
     * Construct a V4Signature from .idsig file.
     */
    public static V4Signature readFrom(File file) {
        try (DataInputStream stream = new DataInputStream(new FileInputStream(file))) {
            return readFrom(stream);
        } catch (IOException e) {
            return null;
        }
    }

    static byte[] readBytes(DataInputStream stream) throws IOException {
        byte[] result = new byte[stream.readInt()];
        stream.read(result);
        return result;
    /**
     * Store the V4Signature to a byte-array.
     */
    public byte[] toByteArray() {
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            try (DataOutputStream steam = new DataOutputStream(byteArrayOutputStream)) {
                this.writeTo(steam);
                steam.flush();
            }
            return byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            return null;
        }
    }

    static V4Signature readFrom(DataInputStream stream) throws IOException {
@@ -49,9 +68,10 @@ public class V4Signature {
        return new V4Signature(verityRootHash, v3Digest, pkcs7SignatureBlock);
    }

    static void writeBytes(DataOutputStream stream, byte[] bytes) throws IOException {
        stream.writeInt(bytes.length);
        stream.write(bytes);
    V4Signature(byte[] verityRootHash, byte[] v3Digest, byte[] pkcs7SignatureBlock) {
        this.verityRootHash = verityRootHash;
        this.v3Digest = v3Digest;
        this.pkcs7SignatureBlock = pkcs7SignatureBlock;
    }

    void writeTo(DataOutputStream stream) throws IOException {
@@ -59,4 +79,15 @@ public class V4Signature {
        writeBytes(stream, this.v3Digest);
        writeBytes(stream, this.pkcs7SignatureBlock);
    }

    private static byte[] readBytes(DataInputStream stream) throws IOException {
        byte[] result = new byte[stream.readInt()];
        stream.read(result);
        return result;
    }

    private static void writeBytes(DataOutputStream stream, byte[] bytes) throws IOException {
        stream.writeInt(bytes.length);
        stream.write(bytes);
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -1156,7 +1156,7 @@ public class SystemConfig {
            addFeature(PackageManager.FEATURE_RAM_NORMAL, 0);
        }

        if (IncrementalManager.isEnabled()) {
        if (IncrementalManager.isFeatureEnabled()) {
            addFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY, 0);
        }

+14 −6
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ import android.os.RevocableFileDescriptor;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.incremental.IncrementalFileStorages;
import android.os.incremental.IncrementalManager;
import android.os.storage.StorageManager;
import android.provider.Settings.Secure;
import android.stats.devicepolicy.DevicePolicyEnums;
@@ -538,17 +539,20 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                throw new IllegalArgumentException(
                        "DataLoader installation of APEX modules is not allowed.");
            }
            if (this.params.dataLoaderParams.getComponentName().getPackageName()
                    == SYSTEM_DATA_LOADER_PACKAGE) {
                assertShellOrSystemCalling("System data loaders");
            }
        }

        if (isStreamingInstallation()) {
        if (isIncrementalInstallation()) {
            if (!IncrementalManager.isAllowed()) {
                throw new IllegalArgumentException("Incremental installation not allowed.");
            }
            if (!isIncrementalInstallationAllowed(mPackageName)) {
                throw new IllegalArgumentException(
                        "Incremental installation of this package is not allowed.");
            }
            if (this.params.dataLoaderParams.getComponentName().getPackageName()
                    == SYSTEM_DATA_LOADER_PACKAGE) {
                assertShellOrSystemCalling("System data loaders");
            }
        }
    }

@@ -2385,12 +2389,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            throw new IllegalStateException(
                    "Cannot add files to non-data loader installation session.");
        }
        if (!isIncrementalInstallation()) {
        if (isStreamingInstallation()) {
            if (location != LOCATION_DATA_APP) {
                throw new IllegalArgumentException(
                        "Non-incremental installation only supports /data/app placement: " + name);
            }
        }
        if (metadata == null) {
            throw new IllegalArgumentException(
                    "DataLoader installation requires valid metadata: " + name);
        }
        // Use installer provided name for now; we always rename later
        if (!FileUtils.isValidExtFilename(name)) {
            throw new IllegalArgumentException("Invalid name: " + name);
+9 −2
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.incremental.V4Signature;
import android.os.storage.StorageManager;
import android.permission.IPermissionManager;
import android.system.ErrnoException;
@@ -3024,9 +3025,15 @@ class PackageManagerShellCommand extends ShellCommand {
                final File file = new File(inPath);
                final String name = file.getName();
                final long size = file.length();
                byte[] metadata = inPath.getBytes(StandardCharsets.UTF_8);
                final byte[] metadata = inPath.getBytes(StandardCharsets.UTF_8);

                session.addFile(LOCATION_DATA_APP, name, size, metadata, null);
                // Try to load a v4 signature for the APK.
                final V4Signature v4signature = V4Signature.readFrom(
                        new File(inPath + V4Signature.EXT));
                final byte[] v4signatureBytes =
                        (v4signature != null) ? v4signature.toByteArray() : null;

                session.addFile(LOCATION_DATA_APP, name, size, metadata, v4signatureBytes);
            }
            return 0;
        } finally {
Loading