summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt43
-rw-r--r--core/java/android/app/ApplicationPackageManager.java11
-rw-r--r--core/java/android/content/pm/Checksum.aidl20
-rw-r--r--core/java/android/content/pm/Checksum.java228
-rw-r--r--core/java/android/content/pm/FileChecksum.aidl (renamed from core/java/android/content/pm/ApkChecksum.aidl)2
-rw-r--r--core/java/android/content/pm/FileChecksum.java (renamed from core/java/android/content/pm/ApkChecksum.java)123
-rw-r--r--core/java/android/content/pm/IPackageInstallerSession.aidl3
-rw-r--r--core/java/android/content/pm/PackageInstaller.java25
-rw-r--r--core/java/android/content/pm/PackageManager.java72
-rw-r--r--non-updatable-api/current.txt43
-rw-r--r--services/core/java/com/android/server/pm/ApkChecksums.java250
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java268
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java1
15 files changed, 271 insertions, 829 deletions
diff --git a/api/current.txt b/api/current.txt
index 24646be7011b..e678d1656fd4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11446,16 +11446,6 @@ package android.content.pm {
field public final float widthFraction;
}
- public final class ApkChecksum implements android.os.Parcelable {
- method public int describeContents();
- method public int getKind();
- method @Nullable public java.security.cert.Certificate getSourceCertificate() throws java.security.cert.CertificateException;
- method @Nullable public String getSplitName();
- method @NonNull public byte[] getValue();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ApkChecksum> CREATOR;
- }
-
public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
ctor public ApplicationInfo();
ctor public ApplicationInfo(android.content.pm.ApplicationInfo);
@@ -11557,21 +11547,6 @@ package android.content.pm {
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ChangedPackages> CREATOR;
}
- public final class Checksum implements android.os.Parcelable {
- method public int describeContents();
- method public int getKind();
- method @NonNull public byte[] getValue();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.Checksum> CREATOR;
- field public static final int PARTIAL_MERKLE_ROOT_1M_SHA256 = 32; // 0x20
- field public static final int PARTIAL_MERKLE_ROOT_1M_SHA512 = 64; // 0x40
- field public static final int WHOLE_MD5 = 2; // 0x2
- field public static final int WHOLE_MERKLE_ROOT_4K_SHA256 = 1; // 0x1
- field public static final int WHOLE_SHA1 = 4; // 0x4
- field public static final int WHOLE_SHA256 = 8; // 0x8
- field public static final int WHOLE_SHA512 = 16; // 0x10
- }
-
public class ComponentInfo extends android.content.pm.PackageItemInfo {
ctor public ComponentInfo();
ctor public ComponentInfo(android.content.pm.ComponentInfo);
@@ -11643,6 +11618,16 @@ package android.content.pm {
field public int version;
}
+ public final class FileChecksum implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getKind();
+ method @Nullable public java.security.cert.Certificate getSourceCertificate() throws java.security.cert.CertificateException;
+ method @Nullable public String getSplitName();
+ method @NonNull public byte[] getValue();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.FileChecksum> CREATOR;
+ }
+
public final class InstallSourceInfo implements android.os.Parcelable {
method public int describeContents();
method @Nullable public String getInitiatingPackageName();
@@ -11863,7 +11848,6 @@ package android.content.pm {
public static class PackageInstaller.Session implements java.io.Closeable {
method public void abandon();
- method public void addChecksums(@NonNull String, @NonNull java.util.List<android.content.pm.Checksum>) throws java.io.IOException;
method public void addChildSessionId(int);
method public void close();
method public void commit(@NonNull android.content.IntentSender);
@@ -12265,6 +12249,8 @@ package android.content.pm {
field public static final int MATCH_SYSTEM_ONLY = 1048576; // 0x100000
field public static final int MATCH_UNINSTALLED_PACKAGES = 8192; // 0x2000
field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80L
+ field public static final int PARTIAL_MERKLE_ROOT_1M_SHA256 = 32; // 0x20
+ field public static final int PARTIAL_MERKLE_ROOT_1M_SHA512 = 64; // 0x40
field public static final int PERMISSION_DENIED = -1; // 0xffffffff
field public static final int PERMISSION_GRANTED = 0; // 0x0
field public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; // 0xffffffff
@@ -12279,6 +12265,11 @@ package android.content.pm {
field public static final int VERIFICATION_ALLOW = 1; // 0x1
field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
+ field public static final int WHOLE_MD5 = 2; // 0x2
+ field public static final int WHOLE_MERKLE_ROOT_4K_SHA256 = 1; // 0x1
+ field public static final int WHOLE_SHA1 = 4; // 0x4
+ field public static final int WHOLE_SHA256 = 8; // 0x8
+ field public static final int WHOLE_SHA512 = 16; // 0x10
}
public static class PackageManager.NameNotFoundException extends android.util.AndroidException {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 066a00732965..2780036d8102 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -16,14 +16,6 @@
package android.app;
-import static android.content.pm.Checksum.PARTIAL_MERKLE_ROOT_1M_SHA256;
-import static android.content.pm.Checksum.PARTIAL_MERKLE_ROOT_1M_SHA512;
-import static android.content.pm.Checksum.WHOLE_MD5;
-import static android.content.pm.Checksum.WHOLE_MERKLE_ROOT_4K_SHA256;
-import static android.content.pm.Checksum.WHOLE_SHA1;
-import static android.content.pm.Checksum.WHOLE_SHA256;
-import static android.content.pm.Checksum.WHOLE_SHA512;
-
import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -40,7 +32,6 @@ import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ChangedPackages;
-import android.content.pm.Checksum;
import android.content.pm.ComponentInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageDataObserver;
@@ -982,7 +973,7 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public void getChecksums(@NonNull String packageName, boolean includeSplits,
- @Checksum.Kind int required, @Nullable List<Certificate> trustedInstallers,
+ @FileChecksumKind int required, @Nullable List<Certificate> trustedInstallers,
@NonNull IntentSender statusReceiver)
throws CertificateEncodingException, IOException, NameNotFoundException {
Objects.requireNonNull(packageName);
diff --git a/core/java/android/content/pm/Checksum.aidl b/core/java/android/content/pm/Checksum.aidl
deleted file mode 100644
index f0ca206fad58..000000000000
--- a/core/java/android/content/pm/Checksum.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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;
-
-parcelable Checksum;
-
diff --git a/core/java/android/content/pm/Checksum.java b/core/java/android/content/pm/Checksum.java
deleted file mode 100644
index 123aaddda7ce..000000000000
--- a/core/java/android/content/pm/Checksum.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * 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;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.util.DataClass;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/**
- * A typed checksum.
- *
- * @see PackageInstaller.Session#addChecksums(String, List)
- */
-@DataClass(genHiddenConstructor = true, genConstDefs = false)
-public final class Checksum implements Parcelable {
- /**
- * Root SHA256 hash of a 4K Merkle tree computed over all file bytes.
- * <a href="https://source.android.com/security/apksigning/v4">See APK Signature Scheme V4</a>.
- * <a href="https://git.kernel.org/pub/scm/fs/fscrypt/fscrypt.git/tree/Documentation/filesystems/fsverity.rst">See fs-verity</a>.
- *
- * @see PackageManager#getChecksums
- */
- public static final int WHOLE_MERKLE_ROOT_4K_SHA256 = 0x00000001;
-
- /**
- * MD5 hash computed over all file bytes.
- *
- * @see PackageManager#getChecksums
- */
- public static final int WHOLE_MD5 = 0x00000002;
-
- /**
- * SHA1 hash computed over all file bytes.
- *
- * @see PackageManager#getChecksums
- */
- public static final int WHOLE_SHA1 = 0x00000004;
-
- /**
- * SHA256 hash computed over all file bytes.
- *
- * @see PackageManager#getChecksums
- */
- public static final int WHOLE_SHA256 = 0x00000008;
-
- /**
- * SHA512 hash computed over all file bytes.
- *
- * @see PackageManager#getChecksums
- */
- public static final int WHOLE_SHA512 = 0x00000010;
-
- /**
- * Root SHA256 hash of a 1M Merkle tree computed over protected content.
- * Excludes signing block.
- * <a href="https://source.android.com/security/apksigning/v2">See APK Signature Scheme V2</a>.
- *
- * @see PackageManager#getChecksums
- */
- public static final int PARTIAL_MERKLE_ROOT_1M_SHA256 = 0x00000020;
-
- /**
- * Root SHA512 hash of a 1M Merkle tree computed over protected content.
- * Excludes signing block.
- * <a href="https://source.android.com/security/apksigning/v2">See APK Signature Scheme V2</a>.
- *
- * @see PackageManager#getChecksums
- */
- public static final int PARTIAL_MERKLE_ROOT_1M_SHA512 = 0x00000040;
-
- /** @hide */
- @IntDef(flag = true, prefix = {"WHOLE_", "PARTIAL_"}, value = {
- WHOLE_MERKLE_ROOT_4K_SHA256,
- WHOLE_MD5,
- WHOLE_SHA1,
- WHOLE_SHA256,
- WHOLE_SHA512,
- PARTIAL_MERKLE_ROOT_1M_SHA256,
- PARTIAL_MERKLE_ROOT_1M_SHA512,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Kind {}
-
- /**
- * Checksum kind.
- */
- private final @Checksum.Kind int mKind;
- /**
- * Checksum value.
- */
- private final @NonNull byte[] mValue;
-
-
-
- // Code below generated by codegen v1.0.15.
- //
- // DO NOT MODIFY!
- // CHECKSTYLE:OFF Generated code
- //
- // To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/Checksum.java
- //
- // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
- // Settings > Editor > Code Style > Formatter Control
- //@formatter:off
-
-
- /**
- * Creates a new Checksum.
- *
- * @param kind
- * Checksum kind.
- * @param value
- * Checksum value.
- * @hide
- */
- @DataClass.Generated.Member
- public Checksum(
- @Checksum.Kind int kind,
- @NonNull byte[] value) {
- this.mKind = kind;
- com.android.internal.util.AnnotationValidations.validate(
- Checksum.Kind.class, null, mKind);
- this.mValue = value;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mValue);
-
- // onConstructed(); // You can define this method to get a callback
- }
-
- /**
- * Checksum kind.
- */
- @DataClass.Generated.Member
- public @Checksum.Kind int getKind() {
- return mKind;
- }
-
- /**
- * Checksum value.
- */
- @DataClass.Generated.Member
- public @NonNull byte[] getValue() {
- return mValue;
- }
-
- @Override
- @DataClass.Generated.Member
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- // You can override field parcelling by defining methods like:
- // void parcelFieldName(Parcel dest, int flags) { ... }
-
- dest.writeInt(mKind);
- dest.writeByteArray(mValue);
- }
-
- @Override
- @DataClass.Generated.Member
- public int describeContents() { return 0; }
-
- /** @hide */
- @SuppressWarnings({"unchecked", "RedundantCast"})
- @DataClass.Generated.Member
- /* package-private */ Checksum(@NonNull Parcel in) {
- // You can override field unparcelling by defining methods like:
- // static FieldType unparcelFieldName(Parcel in) { ... }
-
- int kind = in.readInt();
- byte[] value = in.createByteArray();
-
- this.mKind = kind;
- com.android.internal.util.AnnotationValidations.validate(
- Checksum.Kind.class, null, mKind);
- this.mValue = value;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mValue);
-
- // onConstructed(); // You can define this method to get a callback
- }
-
- @DataClass.Generated.Member
- public static final @NonNull Parcelable.Creator<Checksum> CREATOR
- = new Parcelable.Creator<Checksum>() {
- @Override
- public Checksum[] newArray(int size) {
- return new Checksum[size];
- }
-
- @Override
- public Checksum createFromParcel(@NonNull Parcel in) {
- return new Checksum(in);
- }
- };
-
- @DataClass.Generated(
- time = 1599845646883L,
- codegenVersion = "1.0.15",
- sourceFile = "frameworks/base/core/java/android/content/pm/Checksum.java",
- inputSignatures = "public static final int WHOLE_MERKLE_ROOT_4K_SHA256\npublic static final int WHOLE_MD5\npublic static final int WHOLE_SHA1\npublic static final int WHOLE_SHA256\npublic static final int WHOLE_SHA512\npublic static final int PARTIAL_MERKLE_ROOT_1M_SHA256\npublic static final int PARTIAL_MERKLE_ROOT_1M_SHA512\nprivate final @android.content.pm.Checksum.Kind int mKind\nprivate final @android.annotation.NonNull byte[] mValue\nclass Checksum extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genConstDefs=false)")
- @Deprecated
- private void __metadata() {}
-
-
- //@formatter:on
- // End of generated code
-
-}
diff --git a/core/java/android/content/pm/ApkChecksum.aidl b/core/java/android/content/pm/FileChecksum.aidl
index 46781fe26677..109f211033c1 100644
--- a/core/java/android/content/pm/ApkChecksum.aidl
+++ b/core/java/android/content/pm/FileChecksum.aidl
@@ -16,5 +16,5 @@
package android.content.pm;
-parcelable ApkChecksum;
+parcelable FileChecksum;
diff --git a/core/java/android/content/pm/ApkChecksum.java b/core/java/android/content/pm/FileChecksum.java
index e087c44d1ed1..55430c2b877b 100644
--- a/core/java/android/content/pm/ApkChecksum.java
+++ b/core/java/android/content/pm/FileChecksum.java
@@ -34,71 +34,51 @@ import java.security.cert.X509Certificate;
import java.util.List;
/**
- * A typed checksum of an APK.
+ * A typed checksum.
*
* @see PackageManager#getChecksums(String, boolean, int, List, IntentSender)
*/
@DataClass(genHiddenConstructor = true)
-@DataClass.Suppress({"getChecksum"})
-public final class ApkChecksum implements Parcelable {
+public final class FileChecksum implements Parcelable {
/**
* Checksum for which split. Null indicates base.apk.
*/
private final @Nullable String mSplitName;
/**
- * Checksum.
+ * Checksum kind.
*/
- private final @NonNull Checksum mChecksum;
+ private final @PackageManager.FileChecksumKind int mKind;
+ /**
+ * Checksum value.
+ */
+ private final @NonNull byte[] mValue;
/**
* For Installer-provided checksums, certificate of the Installer/AppStore.
*/
private final @Nullable byte[] mSourceCertificate;
/**
- * Constructor, internal use only.
+ * Constructor, internal use only
*
* @hide
*/
- public ApkChecksum(@Nullable String splitName, @Checksum.Kind int kind,
+ public FileChecksum(@Nullable String splitName, @PackageManager.FileChecksumKind int kind,
@NonNull byte[] value) {
- this(splitName, new Checksum(kind, value), (byte[]) null);
+ this(splitName, kind, value, (byte[]) null);
}
/**
- * Constructor, internal use only.
+ * Constructor, internal use only
*
* @hide
*/
- public ApkChecksum(@Nullable String splitName, @Checksum.Kind int kind,
+ public FileChecksum(@Nullable String splitName, @PackageManager.FileChecksumKind int kind,
@NonNull byte[] value, @Nullable Certificate sourceCertificate)
throws CertificateEncodingException {
- this(splitName, new Checksum(kind, value),
+ this(splitName, kind, value,
(sourceCertificate != null) ? sourceCertificate.getEncoded() : null);
}
-
- /**
- * Checksum kind.
- */
- public @Checksum.Kind int getKind() {
- return mChecksum.getKind();
- }
-
- /**
- * Checksum value.
- */
- public @NonNull byte[] getValue() {
- return mChecksum.getValue();
- }
-
- /**
- * Returns raw bytes representing encoded certificate of the source of this checksum.
- * @hide
- */
- public @Nullable byte[] getSourceCertificateBytes() {
- return mSourceCertificate;
- }
-
/**
* Certificate of the source of this checksum.
* @throws CertificateException in case when certificate can't be re-created from serialized
@@ -122,7 +102,7 @@ public final class ApkChecksum implements Parcelable {
// CHECKSTYLE:OFF Generated code
//
// To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/ApkChecksum.java
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/FileChecksum.java
//
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
// Settings > Editor > Code Style > Formatter Control
@@ -130,25 +110,31 @@ public final class ApkChecksum implements Parcelable {
/**
- * Creates a new ApkChecksum.
+ * Creates a new FileChecksum.
*
* @param splitName
* Checksum for which split. Null indicates base.apk.
- * @param checksum
- * Checksum.
+ * @param kind
+ * Checksum kind.
+ * @param value
+ * Checksum value.
* @param sourceCertificate
* For Installer-provided checksums, certificate of the Installer/AppStore.
* @hide
*/
@DataClass.Generated.Member
- public ApkChecksum(
+ public FileChecksum(
@Nullable String splitName,
- @NonNull Checksum checksum,
+ @PackageManager.FileChecksumKind int kind,
+ @NonNull byte[] value,
@Nullable byte[] sourceCertificate) {
this.mSplitName = splitName;
- this.mChecksum = checksum;
+ this.mKind = kind;
com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mChecksum);
+ PackageManager.FileChecksumKind.class, null, mKind);
+ this.mValue = value;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mValue);
this.mSourceCertificate = sourceCertificate;
// onConstructed(); // You can define this method to get a callback
@@ -162,6 +148,22 @@ public final class ApkChecksum implements Parcelable {
return mSplitName;
}
+ /**
+ * Checksum kind.
+ */
+ @DataClass.Generated.Member
+ public @PackageManager.FileChecksumKind int getKind() {
+ return mKind;
+ }
+
+ /**
+ * Checksum value.
+ */
+ @DataClass.Generated.Member
+ public @NonNull byte[] getValue() {
+ return mValue;
+ }
+
@Override
@DataClass.Generated.Member
public void writeToParcel(@NonNull Parcel dest, int flags) {
@@ -170,10 +172,11 @@ public final class ApkChecksum implements Parcelable {
byte flg = 0;
if (mSplitName != null) flg |= 0x1;
- if (mSourceCertificate != null) flg |= 0x4;
+ if (mSourceCertificate != null) flg |= 0x8;
dest.writeByte(flg);
if (mSplitName != null) dest.writeString(mSplitName);
- dest.writeTypedObject(mChecksum, flags);
+ dest.writeInt(mKind);
+ dest.writeByteArray(mValue);
if (mSourceCertificate != null) dest.writeByteArray(mSourceCertificate);
}
@@ -184,43 +187,47 @@ public final class ApkChecksum implements Parcelable {
/** @hide */
@SuppressWarnings({"unchecked", "RedundantCast"})
@DataClass.Generated.Member
- /* package-private */ ApkChecksum(@NonNull Parcel in) {
+ /* package-private */ FileChecksum(@NonNull Parcel in) {
// You can override field unparcelling by defining methods like:
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
String splitName = (flg & 0x1) == 0 ? null : in.readString();
- Checksum checksum = (Checksum) in.readTypedObject(Checksum.CREATOR);
- byte[] sourceCertificate = (flg & 0x4) == 0 ? null : in.createByteArray();
+ int kind = in.readInt();
+ byte[] value = in.createByteArray();
+ byte[] sourceCertificate = (flg & 0x8) == 0 ? null : in.createByteArray();
this.mSplitName = splitName;
- this.mChecksum = checksum;
+ this.mKind = kind;
+ com.android.internal.util.AnnotationValidations.validate(
+ PackageManager.FileChecksumKind.class, null, mKind);
+ this.mValue = value;
com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mChecksum);
+ NonNull.class, null, mValue);
this.mSourceCertificate = sourceCertificate;
// onConstructed(); // You can define this method to get a callback
}
@DataClass.Generated.Member
- public static final @NonNull Parcelable.Creator<ApkChecksum> CREATOR
- = new Parcelable.Creator<ApkChecksum>() {
+ public static final @NonNull Parcelable.Creator<FileChecksum> CREATOR
+ = new Parcelable.Creator<FileChecksum>() {
@Override
- public ApkChecksum[] newArray(int size) {
- return new ApkChecksum[size];
+ public FileChecksum[] newArray(int size) {
+ return new FileChecksum[size];
}
@Override
- public ApkChecksum createFromParcel(@NonNull Parcel in) {
- return new ApkChecksum(in);
+ public FileChecksum createFromParcel(@NonNull Parcel in) {
+ return new FileChecksum(in);
}
};
@DataClass.Generated(
- time = 1599845645160L,
+ time = 1598322801861L,
codegenVersion = "1.0.15",
- sourceFile = "frameworks/base/core/java/android/content/pm/ApkChecksum.java",
- inputSignatures = "private final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.NonNull android.content.pm.Checksum mChecksum\nprivate final @android.annotation.Nullable byte[] mSourceCertificate\npublic @android.content.pm.Checksum.Kind int getKind()\npublic @android.annotation.NonNull byte[] getValue()\npublic @android.annotation.Nullable byte[] getSourceCertificateBytes()\npublic @android.annotation.Nullable java.security.cert.Certificate getSourceCertificate()\nclass ApkChecksum extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
+ sourceFile = "frameworks/base/core/java/android/content/pm/FileChecksum.java",
+ inputSignatures = "private final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.content.pm.PackageManager.FileChecksumKind int mKind\nprivate final @android.annotation.NonNull byte[] mValue\nprivate final @android.annotation.Nullable byte[] mSourceCertificate\npublic @android.annotation.Nullable java.security.cert.Certificate getSourceCertificate()\nclass FileChecksum extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index 6ccbc36e26f6..fc20263fe00a 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -16,7 +16,6 @@
package android.content.pm;
-import android.content.pm.Checksum;
import android.content.pm.DataLoaderParamsParcel;
import android.content.pm.IPackageInstallObserver2;
import android.content.IntentSender;
@@ -34,8 +33,6 @@ interface IPackageInstallerSession {
void write(String name, long offsetBytes, long lengthBytes, in ParcelFileDescriptor fd);
- void addChecksums(String name, in Checksum[] checksums);
-
void removeSplit(String splitName);
void close();
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 9eb95a3f6707..e6ea04433114 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1219,31 +1219,6 @@ public class PackageInstaller {
}
/**
- * Adds installer-provided checksums for the APK file in session.
- *
- * @param name previously written as part of this session.
- * @param checksums installer intends to make available via
- * {@link PackageManager#getChecksums(String, boolean, int, List,
- * IntentSender)}.
- * @throws SecurityException if called after the session has been
- * committed or abandoned.
- */
- public void addChecksums(@NonNull String name, @NonNull List<Checksum> checksums)
- throws IOException {
- Objects.requireNonNull(name);
- Objects.requireNonNull(checksums);
-
- try {
- mSession.addChecksums(name, checksums.toArray(new Checksum[checksums.size()]));
- } catch (RuntimeException e) {
- ExceptionUtils.maybeUnwrapIOException(e);
- throw e;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Attempt to commit everything staged in this session. This may require
* user intervention, and so it may not happen immediately. The final
* result of the commit will be reported through the given callback.
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e68df3383642..d2395ec9f69f 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -7844,6 +7844,74 @@ public abstract class PackageManager {
}
/**
+ * Root SHA256 hash of a 4K Merkle tree computed over all file bytes.
+ * <a href="https://source.android.com/security/apksigning/v4">See APK Signature Scheme V4</a>.
+ * <a href="https://git.kernel.org/pub/scm/fs/fscrypt/fscrypt.git/tree/Documentation/filesystems/fsverity.rst">See fs-verity</a>.
+ *
+ * @see #getChecksums
+ */
+ public static final int WHOLE_MERKLE_ROOT_4K_SHA256 = 0x00000001;
+
+ /**
+ * MD5 hash computed over all file bytes.
+ *
+ * @see #getChecksums
+ */
+ public static final int WHOLE_MD5 = 0x00000002;
+
+ /**
+ * SHA1 hash computed over all file bytes.
+ *
+ * @see #getChecksums
+ */
+ public static final int WHOLE_SHA1 = 0x00000004;
+
+ /**
+ * SHA256 hash computed over all file bytes.
+ *
+ * @see #getChecksums
+ */
+ public static final int WHOLE_SHA256 = 0x00000008;
+
+ /**
+ * SHA512 hash computed over all file bytes.
+ *
+ * @see #getChecksums
+ */
+ public static final int WHOLE_SHA512 = 0x00000010;
+
+ /**
+ * Root SHA256 hash of a 1M Merkle tree computed over protected content.
+ * Excludes signing block.
+ * <a href="https://source.android.com/security/apksigning/v2">See APK Signature Scheme V2</a>.
+ *
+ * @see #getChecksums
+ */
+ public static final int PARTIAL_MERKLE_ROOT_1M_SHA256 = 0x00000020;
+
+ /**
+ * Root SHA512 hash of a 1M Merkle tree computed over protected content.
+ * Excludes signing block.
+ * <a href="https://source.android.com/security/apksigning/v2">See APK Signature Scheme V2</a>.
+ *
+ * @see #getChecksums
+ */
+ public static final int PARTIAL_MERKLE_ROOT_1M_SHA512 = 0x00000040;
+
+ /** @hide */
+ @IntDef(flag = true, prefix = {"WHOLE_", "PARTIAL_"}, value = {
+ WHOLE_MERKLE_ROOT_4K_SHA256,
+ WHOLE_MD5,
+ WHOLE_SHA1,
+ WHOLE_SHA256,
+ WHOLE_SHA512,
+ PARTIAL_MERKLE_ROOT_1M_SHA256,
+ PARTIAL_MERKLE_ROOT_1M_SHA512,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FileChecksumKind {}
+
+ /**
* Trust any Installer to provide checksums for the package.
* @see #getChecksums
*/
@@ -7872,12 +7940,12 @@ public abstract class PackageManager {
* {@link #TRUST_ALL} will return checksums from any Installer,
* {@link #TRUST_NONE} disables optimized Installer-enforced checksums.
* @param statusReceiver called once when the results are available as
- * {@link #EXTRA_CHECKSUMS} of type ApkChecksum[].
+ * {@link #EXTRA_CHECKSUMS} of type FileChecksum[].
* @throws CertificateEncodingException if an encoding error occurs for trustedInstallers.
* @throws NameNotFoundException if a package with the given name cannot be found on the system.
*/
public void getChecksums(@NonNull String packageName, boolean includeSplits,
- @Checksum.Kind int required, @Nullable List<Certificate> trustedInstallers,
+ @FileChecksumKind int required, @Nullable List<Certificate> trustedInstallers,
@NonNull IntentSender statusReceiver)
throws CertificateEncodingException, IOException, NameNotFoundException {
throw new UnsupportedOperationException("getChecksums not implemented in subclass");
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index d3460856f71c..bb40e24a68ac 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -11446,16 +11446,6 @@ package android.content.pm {
field public final float widthFraction;
}
- public final class ApkChecksum implements android.os.Parcelable {
- method public int describeContents();
- method public int getKind();
- method @Nullable public java.security.cert.Certificate getSourceCertificate() throws java.security.cert.CertificateException;
- method @Nullable public String getSplitName();
- method @NonNull public byte[] getValue();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ApkChecksum> CREATOR;
- }
-
public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
ctor public ApplicationInfo();
ctor public ApplicationInfo(android.content.pm.ApplicationInfo);
@@ -11557,21 +11547,6 @@ package android.content.pm {
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ChangedPackages> CREATOR;
}
- public final class Checksum implements android.os.Parcelable {
- method public int describeContents();
- method public int getKind();
- method @NonNull public byte[] getValue();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.Checksum> CREATOR;
- field public static final int PARTIAL_MERKLE_ROOT_1M_SHA256 = 32; // 0x20
- field public static final int PARTIAL_MERKLE_ROOT_1M_SHA512 = 64; // 0x40
- field public static final int WHOLE_MD5 = 2; // 0x2
- field public static final int WHOLE_MERKLE_ROOT_4K_SHA256 = 1; // 0x1
- field public static final int WHOLE_SHA1 = 4; // 0x4
- field public static final int WHOLE_SHA256 = 8; // 0x8
- field public static final int WHOLE_SHA512 = 16; // 0x10
- }
-
public class ComponentInfo extends android.content.pm.PackageItemInfo {
ctor public ComponentInfo();
ctor public ComponentInfo(android.content.pm.ComponentInfo);
@@ -11643,6 +11618,16 @@ package android.content.pm {
field public int version;
}
+ public final class FileChecksum implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getKind();
+ method @Nullable public java.security.cert.Certificate getSourceCertificate() throws java.security.cert.CertificateException;
+ method @Nullable public String getSplitName();
+ method @NonNull public byte[] getValue();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.FileChecksum> CREATOR;
+ }
+
public final class InstallSourceInfo implements android.os.Parcelable {
method public int describeContents();
method @Nullable public String getInitiatingPackageName();
@@ -11863,7 +11848,6 @@ package android.content.pm {
public static class PackageInstaller.Session implements java.io.Closeable {
method public void abandon();
- method public void addChecksums(@NonNull String, @NonNull java.util.List<android.content.pm.Checksum>) throws java.io.IOException;
method public void addChildSessionId(int);
method public void close();
method public void commit(@NonNull android.content.IntentSender);
@@ -12265,6 +12249,8 @@ package android.content.pm {
field public static final int MATCH_SYSTEM_ONLY = 1048576; // 0x100000
field public static final int MATCH_UNINSTALLED_PACKAGES = 8192; // 0x2000
field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80L
+ field public static final int PARTIAL_MERKLE_ROOT_1M_SHA256 = 32; // 0x20
+ field public static final int PARTIAL_MERKLE_ROOT_1M_SHA512 = 64; // 0x40
field public static final int PERMISSION_DENIED = -1; // 0xffffffff
field public static final int PERMISSION_GRANTED = 0; // 0x0
field public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; // 0xffffffff
@@ -12279,6 +12265,11 @@ package android.content.pm {
field public static final int VERIFICATION_ALLOW = 1; // 0x1
field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
+ field public static final int WHOLE_MD5 = 2; // 0x2
+ field public static final int WHOLE_MERKLE_ROOT_4K_SHA256 = 1; // 0x1
+ field public static final int WHOLE_SHA1 = 4; // 0x4
+ field public static final int WHOLE_SHA256 = 8; // 0x8
+ field public static final int WHOLE_SHA512 = 16; // 0x10
}
public static class PackageManager.NameNotFoundException extends android.util.AndroidException {
diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java
index c6c80aef4432..0338ed802436 100644
--- a/services/core/java/com/android/server/pm/ApkChecksums.java
+++ b/services/core/java/com/android/server/pm/ApkChecksums.java
@@ -16,15 +16,14 @@
package com.android.server.pm;
-import static android.content.pm.Checksum.PARTIAL_MERKLE_ROOT_1M_SHA256;
-import static android.content.pm.Checksum.PARTIAL_MERKLE_ROOT_1M_SHA512;
-import static android.content.pm.Checksum.WHOLE_MD5;
-import static android.content.pm.Checksum.WHOLE_MERKLE_ROOT_4K_SHA256;
-import static android.content.pm.Checksum.WHOLE_SHA1;
-import static android.content.pm.Checksum.WHOLE_SHA256;
-import static android.content.pm.Checksum.WHOLE_SHA512;
import static android.content.pm.PackageManager.EXTRA_CHECKSUMS;
-import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
+import static android.content.pm.PackageManager.PARTIAL_MERKLE_ROOT_1M_SHA256;
+import static android.content.pm.PackageManager.PARTIAL_MERKLE_ROOT_1M_SHA512;
+import static android.content.pm.PackageManager.WHOLE_MD5;
+import static android.content.pm.PackageManager.WHOLE_MERKLE_ROOT_4K_SHA256;
+import static android.content.pm.PackageManager.WHOLE_SHA1;
+import static android.content.pm.PackageManager.WHOLE_SHA256;
+import static android.content.pm.PackageManager.WHOLE_SHA512;
import static android.util.apk.ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256;
import static android.util.apk.ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA512;
import static android.util.apk.ApkSigningBlockUtils.CONTENT_DIGEST_VERITY_CHUNKED_SHA256;
@@ -34,16 +33,14 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
-import android.content.pm.ApkChecksum;
-import android.content.pm.Checksum;
+import android.content.pm.FileChecksum;
+import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
-import android.content.pm.Signature;
import android.os.Handler;
import android.os.SystemClock;
import android.os.incremental.IncrementalManager;
import android.os.incremental.IncrementalStorage;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
import android.util.apk.ApkSignatureSchemeV2Verifier;
@@ -60,26 +57,18 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.security.VerityUtils;
import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* Provides checksums for APK.
@@ -87,8 +76,6 @@ import java.util.Set;
public class ApkChecksums {
static final String TAG = "ApkChecksums";
- private static final String DIGESTS_FILE_EXTENSION = ".digests";
-
// MessageDigest algorithms.
static final String ALGO_MD5 = "MD5";
static final String ALGO_SHA1 = "SHA1";
@@ -144,100 +131,6 @@ public class ApkChecksums {
}
/**
- * Return the digests path associated with the given code path
- * (replaces '.apk' extension with '.digests')
- *
- * @throws IllegalArgumentException if the code path is not an .apk.
- */
- public static String buildDigestsPathForApk(String codePath) {
- if (!PackageParser.isApkPath(codePath)) {
- throw new IllegalStateException("Code path is not an apk " + codePath);
- }
- return codePath.substring(0, codePath.length() - APK_FILE_EXTENSION.length())
- + DIGESTS_FILE_EXTENSION;
- }
-
- /**
- * Search for the digests file associated with the given target file.
- * If it exists, the method returns the digests file; otherwise it returns null.
- */
- public static File findDigestsForFile(File targetFile) {
- String digestsPath = buildDigestsPathForApk(targetFile.getAbsolutePath());
- File digestsFile = new File(digestsPath);
- return digestsFile.exists() ? digestsFile : null;
- }
-
- /**
- * Serialize checksums to file in binary format.
- */
- public static void writeChecksums(File file, ApkChecksum[] checksums)
- throws IOException, CertificateException {
- try (OutputStream os = new FileOutputStream(file);
- DataOutputStream dos = new DataOutputStream(os)) {
- dos.writeInt(checksums.length);
- for (ApkChecksum checksum : checksums) {
- final String splitName = checksum.getSplitName();
- if (splitName == null) {
- dos.writeInt(-1);
- } else {
- dos.writeInt(splitName.length());
- dos.writeUTF(splitName);
- }
-
- dos.writeInt(checksum.getKind());
-
- final byte[] valueBytes = checksum.getValue();
- dos.writeInt(valueBytes.length);
- dos.write(valueBytes);
-
- final Certificate cert = checksum.getSourceCertificate();
- final byte[] certBytes = (cert == null) ? null : cert.getEncoded();
- if (certBytes == null) {
- dos.writeInt(-1);
- } else {
- dos.writeInt(certBytes.length);
- dos.write(certBytes);
- }
- }
- }
- }
-
- /**
- * Deserialize array of checksums previously stored in
- * {@link #writeChecksums(File, ApkChecksum[])}.
- */
- private static ApkChecksum[] readChecksums(File file) throws IOException {
- try (InputStream is = new FileInputStream(file);
- DataInputStream dis = new DataInputStream(is)) {
- final int size = dis.readInt();
- ApkChecksum[] checksums = new ApkChecksum[size];
- for (int i = 0; i < size; ++i) {
- final String splitName;
- if (dis.readInt() < 0) {
- splitName = null;
- } else {
- splitName = dis.readUTF();
- }
- final int kind = dis.readInt();
- final byte[] valueBytes = new byte[dis.readInt()];
- dis.read(valueBytes);
- final byte[] certBytes;
- final int certBytesLength = dis.readInt();
- if (certBytesLength < 0) {
- certBytes = null;
- } else {
- certBytes = new byte[certBytesLength];
- dis.read(certBytes);
- }
- checksums[i] = new ApkChecksum(splitName, new Checksum(kind, valueBytes),
- certBytes);
- }
- return checksums;
- }
- }
-
-
- /**
* Fetch or calculate checksums for the collection of files.
*
* @param filesToChecksum split name, null for base and File to fetch checksums for
@@ -249,20 +142,20 @@ public class ApkChecksums {
* @param statusReceiver to receive the resulting checksums
*/
public static void getChecksums(List<Pair<String, File>> filesToChecksum,
- @Checksum.Kind int optional,
- @Checksum.Kind int required,
+ @PackageManager.FileChecksumKind int optional,
+ @PackageManager.FileChecksumKind int required,
@Nullable Certificate[] trustedInstallers,
@NonNull IntentSender statusReceiver,
@NonNull Injector injector) {
- List<Map<Integer, ApkChecksum>> result = new ArrayList<>(filesToChecksum.size());
+ List<Map<Integer, FileChecksum>> result = new ArrayList<>(filesToChecksum.size());
for (int i = 0, size = filesToChecksum.size(); i < size; ++i) {
final String split = filesToChecksum.get(i).first;
final File file = filesToChecksum.get(i).second;
- Map<Integer, ApkChecksum> checksums = new ArrayMap<>();
+ Map<Integer, FileChecksum> checksums = new ArrayMap<>();
result.add(checksums);
try {
- getAvailableApkChecksums(split, file, optional | required, trustedInstallers,
+ getAvailableFileChecksums(split, file, optional | required, trustedInstallers,
checksums);
} catch (Throwable e) {
Slog.e(TAG, "Preferred checksum calculation error", e);
@@ -275,18 +168,18 @@ public class ApkChecksums {
}
private static void processRequiredChecksums(List<Pair<String, File>> filesToChecksum,
- List<Map<Integer, ApkChecksum>> result,
- @Checksum.Kind int required,
+ List<Map<Integer, FileChecksum>> result,
+ @PackageManager.FileChecksumKind int required,
@NonNull IntentSender statusReceiver,
@NonNull Injector injector,
long startTime) {
final boolean timeout =
SystemClock.uptimeMillis() - startTime >= PROCESS_REQUIRED_CHECKSUMS_TIMEOUT_MILLIS;
- List<ApkChecksum> allChecksums = new ArrayList<>();
+ List<FileChecksum> allChecksums = new ArrayList<>();
for (int i = 0, size = filesToChecksum.size(); i < size; ++i) {
final String split = filesToChecksum.get(i).first;
final File file = filesToChecksum.get(i).second;
- Map<Integer, ApkChecksum> checksums = result.get(i);
+ Map<Integer, FileChecksum> checksums = result.get(i);
try {
if (!timeout || required != 0) {
@@ -299,7 +192,7 @@ public class ApkChecksums {
return;
}
- getRequiredApkChecksums(split, file, required, checksums);
+ getRequiredFileChecksums(split, file, required, checksums);
}
allChecksums.addAll(checksums.values());
} catch (Throwable e) {
@@ -309,7 +202,7 @@ public class ApkChecksums {
final Intent intent = new Intent();
intent.putExtra(EXTRA_CHECKSUMS,
- allChecksums.toArray(new ApkChecksum[allChecksums.size()]));
+ allChecksums.toArray(new FileChecksum[allChecksums.size()]));
try {
statusReceiver.sendIntent(injector.getContext(), 1, intent, null, null);
@@ -329,16 +222,16 @@ public class ApkChecksums {
* [] - trust nobody.
* @param checksums resulting checksums
*/
- private static void getAvailableApkChecksums(String split, File file,
- @Checksum.Kind int kinds,
+ private static void getAvailableFileChecksums(String split, File file,
+ @PackageManager.FileChecksumKind int kinds,
@Nullable Certificate[] trustedInstallers,
- Map<Integer, ApkChecksum> checksums) {
+ Map<Integer, FileChecksum> checksums) {
final String filePath = file.getAbsolutePath();
// Always available: FSI or IncFs.
if (isRequired(WHOLE_MERKLE_ROOT_4K_SHA256, kinds, checksums)) {
// Hashes in fs-verity and IncFS are always verified.
- ApkChecksum checksum = extractHashFromFS(split, filePath);
+ FileChecksum checksum = extractHashFromFS(split, filePath);
if (checksum != null) {
checksums.put(checksum.getKind(), checksum);
}
@@ -347,40 +240,22 @@ public class ApkChecksums {
// System enforced: v2/v3.
if (isRequired(PARTIAL_MERKLE_ROOT_1M_SHA256, kinds, checksums) || isRequired(
PARTIAL_MERKLE_ROOT_1M_SHA512, kinds, checksums)) {
- Map<Integer, ApkChecksum> v2v3checksums = extractHashFromV2V3Signature(
+ Map<Integer, FileChecksum> v2v3checksums = extractHashFromV2V3Signature(
split, filePath, kinds);
if (v2v3checksums != null) {
checksums.putAll(v2v3checksums);
}
}
- if (trustedInstallers == null || trustedInstallers.length > 0) {
- final File digestsFile = new File(buildDigestsPathForApk(filePath));
- if (digestsFile.exists()) {
- try {
- final ApkChecksum[] digests = readChecksums(digestsFile);
- final Set<Signature> trusted = convertToSet(trustedInstallers);
- for (ApkChecksum digest : digests) {
- if (isRequired(digest.getKind(), kinds, checksums) && isTrusted(digest,
- trusted)) {
- checksums.put(digest.getKind(), digest);
- }
- }
- } catch (IOException e) {
- Slog.e(TAG, "Error reading .digests", e);
- } catch (CertificateEncodingException e) {
- Slog.e(TAG, "Error encoding trustedInstallers", e);
- }
- }
- }
+ // TODO(b/160605420): Installer provided.
}
/**
* Whether the file is available for checksumming or we need to wait.
*/
private static boolean needToWait(File file,
- @Checksum.Kind int kinds,
- Map<Integer, ApkChecksum> checksums,
+ @PackageManager.FileChecksumKind int kinds,
+ Map<Integer, FileChecksum> checksums,
@NonNull Injector injector) throws IOException {
if (!isRequired(WHOLE_MERKLE_ROOT_4K_SHA256, kinds, checksums)
&& !isRequired(WHOLE_MD5, kinds, checksums)
@@ -399,13 +274,12 @@ public class ApkChecksums {
IncrementalManager manager = injector.getIncrementalManager();
if (manager == null) {
- Slog.e(TAG, "IncrementalManager is missing.");
- return false;
+ throw new IllegalStateException("IncrementalManager is missing.");
}
IncrementalStorage storage = manager.openStorage(filePath);
if (storage == null) {
- Slog.e(TAG, "IncrementalStorage is missing for a path on IncFs: " + filePath);
- return false;
+ throw new IllegalStateException(
+ "IncrementalStorage is missing for a path on IncFs: " + filePath);
}
return !storage.isFileFullyLoaded(filePath);
@@ -419,9 +293,9 @@ public class ApkChecksums {
* @param kinds mask to forcefully calculate if not available
* @param checksums resulting checksums
*/
- private static void getRequiredApkChecksums(String split, File file,
- @Checksum.Kind int kinds,
- Map<Integer, ApkChecksum> checksums) {
+ private static void getRequiredFileChecksums(String split, File file,
+ @PackageManager.FileChecksumKind int kinds,
+ Map<Integer, FileChecksum> checksums) {
final String filePath = file.getAbsolutePath();
// Manually calculating required checksums if not readily available.
@@ -436,7 +310,7 @@ public class ApkChecksums {
}
});
checksums.put(WHOLE_MERKLE_ROOT_4K_SHA256,
- new ApkChecksum(split, WHOLE_MERKLE_ROOT_4K_SHA256, generatedRootHash));
+ new FileChecksum(split, WHOLE_MERKLE_ROOT_4K_SHA256, generatedRootHash));
} catch (IOException | NoSuchAlgorithmException | DigestException e) {
Slog.e(TAG, "Error calculating WHOLE_MERKLE_ROOT_4K_SHA256", e);
}
@@ -450,8 +324,8 @@ public class ApkChecksums {
calculatePartialChecksumsIfRequested(checksums, split, file, kinds);
}
- private static boolean isRequired(@Checksum.Kind int kind,
- @Checksum.Kind int kinds, Map<Integer, ApkChecksum> checksums) {
+ private static boolean isRequired(@PackageManager.FileChecksumKind int kind,
+ @PackageManager.FileChecksumKind int kinds, Map<Integer, FileChecksum> checksums) {
if ((kinds & kind) == 0) {
return false;
}
@@ -461,36 +335,12 @@ public class ApkChecksums {
return true;
}
- /**
- * Signature class provides a fast way to compare certificates using their hashes.
- * The hash is exactly the same as in X509/Certificate.
- */
- private static Set<Signature> convertToSet(@Nullable Certificate[] array) throws
- CertificateEncodingException {
- if (array == null) {
- return null;
- }
- final Set<Signature> set = new ArraySet<>(array.length);
- for (Certificate item : array) {
- set.add(new Signature(item.getEncoded()));
- }
- return set;
- }
-
- private static boolean isTrusted(ApkChecksum checksum, Set<Signature> trusted) {
- if (trusted == null) {
- return true;
- }
- final Signature signature = new Signature(checksum.getSourceCertificateBytes());
- return trusted.contains(signature);
- }
-
- private static ApkChecksum extractHashFromFS(String split, String filePath) {
+ private static FileChecksum extractHashFromFS(String split, String filePath) {
// verity first
{
byte[] hash = VerityUtils.getFsverityRootHash(filePath);
if (hash != null) {
- return new ApkChecksum(split, WHOLE_MERKLE_ROOT_4K_SHA256, hash);
+ return new FileChecksum(split, WHOLE_MERKLE_ROOT_4K_SHA256, hash);
}
}
// v4 next
@@ -500,7 +350,7 @@ public class ApkChecksums {
byte[] hash = signer.contentDigests.getOrDefault(CONTENT_DIGEST_VERITY_CHUNKED_SHA256,
null);
if (hash != null) {
- return new ApkChecksum(split, WHOLE_MERKLE_ROOT_4K_SHA256, hash);
+ return new FileChecksum(split, WHOLE_MERKLE_ROOT_4K_SHA256, hash);
}
} catch (SignatureNotFoundException e) {
// Nothing
@@ -510,7 +360,7 @@ public class ApkChecksums {
return null;
}
- private static Map<Integer, ApkChecksum> extractHashFromV2V3Signature(
+ private static Map<Integer, FileChecksum> extractHashFromV2V3Signature(
String split, String filePath, int kinds) {
Map<Integer, byte[]> contentDigests = null;
try {
@@ -527,19 +377,19 @@ public class ApkChecksums {
return null;
}
- Map<Integer, ApkChecksum> checksums = new ArrayMap<>();
+ Map<Integer, FileChecksum> checksums = new ArrayMap<>();
if ((kinds & PARTIAL_MERKLE_ROOT_1M_SHA256) != 0) {
byte[] hash = contentDigests.getOrDefault(CONTENT_DIGEST_CHUNKED_SHA256, null);
if (hash != null) {
checksums.put(PARTIAL_MERKLE_ROOT_1M_SHA256,
- new ApkChecksum(split, PARTIAL_MERKLE_ROOT_1M_SHA256, hash));
+ new FileChecksum(split, PARTIAL_MERKLE_ROOT_1M_SHA256, hash));
}
}
if ((kinds & PARTIAL_MERKLE_ROOT_1M_SHA512) != 0) {
byte[] hash = contentDigests.getOrDefault(CONTENT_DIGEST_CHUNKED_SHA512, null);
if (hash != null) {
checksums.put(PARTIAL_MERKLE_ROOT_1M_SHA512,
- new ApkChecksum(split, PARTIAL_MERKLE_ROOT_1M_SHA512, hash));
+ new FileChecksum(split, PARTIAL_MERKLE_ROOT_1M_SHA512, hash));
}
}
return checksums;
@@ -561,17 +411,17 @@ public class ApkChecksums {
}
}
- private static void calculateChecksumIfRequested(Map<Integer, ApkChecksum> checksums,
+ private static void calculateChecksumIfRequested(Map<Integer, FileChecksum> checksums,
String split, File file, int required, int kind) {
if ((required & kind) != 0 && !checksums.containsKey(kind)) {
- final byte[] checksum = getApkChecksum(file, kind);
+ final byte[] checksum = getFileChecksum(file, kind);
if (checksum != null) {
- checksums.put(kind, new ApkChecksum(split, kind, checksum));
+ checksums.put(kind, new FileChecksum(split, kind, checksum));
}
}
}
- private static byte[] getApkChecksum(File file, int kind) {
+ private static byte[] getFileChecksum(File file, int kind) {
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis)) {
byte[] dataBytes = new byte[512 * 1024];
@@ -616,7 +466,7 @@ public class ApkChecksums {
}
}
- private static void calculatePartialChecksumsIfRequested(Map<Integer, ApkChecksum> checksums,
+ private static void calculatePartialChecksumsIfRequested(Map<Integer, FileChecksum> checksums,
String split, File file, int required) {
boolean needSignatureSha256 =
(required & PARTIAL_MERKLE_ROOT_1M_SHA256) != 0 && !checksums.containsKey(
@@ -650,7 +500,7 @@ public class ApkChecksums {
for (int i = 0, size = digestAlgos.length; i < size; ++i) {
int checksumKind = getChecksumKindForContentDigestAlgo(digestAlgos[i]);
if (checksumKind != -1) {
- checksums.put(checksumKind, new ApkChecksum(split, checksumKind, digests[i]));
+ checksums.put(checksumKind, new FileChecksum(split, checksumKind, digests[i]));
}
}
} catch (IOException | DigestException e) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index f52db5fb5f2f..155af82289d4 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -732,9 +732,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
installerAttributionTag);
session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
mInstallThread.getLooper(), mStagingManager, sessionId, userId, callingUid,
- installSource, params, createdMillis, stageDir, stageCid, null, null, false, false,
- false, false, null, SessionInfo.INVALID_ID, false, false, false,
- SessionInfo.STAGED_SESSION_NO_ERROR, "");
+ installSource, params, createdMillis,
+ stageDir, stageCid, null, false, false, false, false, null, SessionInfo.INVALID_ID,
+ false, false, false, SessionInfo.STAGED_SESSION_NO_ERROR, "");
synchronized (mSessions) {
mSessions.put(sessionId, session);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 0ab1ac206f5b..ca125320bbf2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -27,7 +27,6 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT;
-import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
import static android.content.pm.PackageParser.APEX_FILE_EXTENSION;
import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
import static android.system.OsConstants.O_CREAT;
@@ -62,9 +61,7 @@ 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.ApplicationInfo;
-import android.content.pm.Checksum;
import android.content.pm.DataLoaderManager;
import android.content.pm.DataLoaderParams;
import android.content.pm.DataLoaderParamsParcel;
@@ -87,7 +84,6 @@ import android.content.pm.PackageParser;
import android.content.pm.PackageParser.ApkLite;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
-import android.content.pm.Signature;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.parsing.ApkLiteParseUtils;
import android.content.pm.parsing.result.ParseResult;
@@ -122,7 +118,6 @@ import android.system.Os;
import android.system.OsConstants;
import android.system.StructStat;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ExceptionUtils;
import android.util.MathUtils;
@@ -158,7 +153,6 @@ import java.io.FileDescriptor;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -182,7 +176,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
static final String TAG_SESSION = "session";
static final String TAG_CHILD_SESSION = "childSession";
static final String TAG_SESSION_FILE = "sessionFile";
- static final String TAG_SESSION_CHECKSUM = "sessionChecksum";
private static final String TAG_GRANTED_RUNTIME_PERMISSION = "granted-runtime-permission";
private static final String TAG_WHITELISTED_RESTRICTED_PERMISSION =
"whitelisted-restricted-permission";
@@ -237,14 +230,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final String ATTR_LENGTH_BYTES = "lengthBytes";
private static final String ATTR_METADATA = "metadata";
private static final String ATTR_SIGNATURE = "signature";
- private static final String ATTR_CHECKSUM_KIND = "checksumKind";
- private static final String ATTR_CHECKSUM_VALUE = "checksumValue";
- private static final String ATTR_CHECKSUM_CERTIFICATE = "checksumCertificate";
private static final String PROPERTY_NAME_INHERIT_NATIVE = "pi.inherit_native_on_dont_kill";
private static final int[] EMPTY_CHILD_SESSION_ARRAY = EmptyArray.INT;
private static final InstallationFile[] EMPTY_INSTALLATION_FILE_ARRAY = {};
- private static final ApkChecksum[] EMPTY_FILE_CHECKSUM_ARRAY = {};
private static final String SYSTEM_DATA_LOADER_PACKAGE = "android";
@@ -391,27 +380,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@GuardedBy("mLock")
private ArraySet<FileEntry> mFiles = new ArraySet<>();
- static class CertifiedChecksum {
- final @NonNull Checksum mChecksum;
- final @NonNull byte[] mCertificate;
-
- CertifiedChecksum(@NonNull Checksum checksum, @NonNull byte[] certificate) {
- mChecksum = checksum;
- mCertificate = certificate;
- }
-
- Checksum getChecksum() {
- return mChecksum;
- }
-
- byte[] getCertificate() {
- return mCertificate;
- }
- }
-
- @GuardedBy("mLock")
- private ArrayMap<String, List<CertifiedChecksum>> mChecksums = new ArrayMap<>();
-
@GuardedBy("mLock")
private boolean mStagedSessionApplied;
@GuardedBy("mLock")
@@ -613,9 +581,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
PackageSessionProvider sessionProvider, Looper looper, StagingManager stagingManager,
int sessionId, int userId, int installerUid, @NonNull InstallSource installSource,
SessionParams params, long createdMillis,
- File stageDir, String stageCid, InstallationFile[] files,
- ArrayMap<String, List<CertifiedChecksum>> checksums,
- boolean prepared, boolean committed, boolean destroyed, boolean sealed,
+ File stageDir, String stageCid, InstallationFile[] files, boolean prepared,
+ boolean committed, boolean destroyed, boolean sealed,
@Nullable int[] childSessionIds, int parentSessionId, boolean isReady,
boolean isFailed, boolean isApplied, int stagedSessionErrorCode,
String stagedSessionErrorMessage) {
@@ -648,7 +615,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
this.mParentSessionId = parentSessionId;
if (files != null) {
- mFiles.ensureCapacity(files.length);
for (int i = 0, size = files.length; i < size; ++i) {
InstallationFile file = files[i];
if (!mFiles.add(new FileEntry(i, file))) {
@@ -658,10 +624,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
- if (checksums != null) {
- mChecksums.putAll(checksums);
- }
-
if (!params.isMultiPackage && (stageDir == null) == (stageCid == null)) {
throw new IllegalArgumentException(
"Exactly one of stageDir or stageCid stage must be set");
@@ -945,45 +907,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
@Override
- public void addChecksums(String name, @NonNull Checksum[] checksums) {
- if (checksums.length == 0) {
- return;
- }
-
- final PackageManagerInternal pmi = LocalServices.getService(
- PackageManagerInternal.class);
- final AndroidPackage callingInstaller = pmi.getPackage(Binder.getCallingUid());
-
- if (callingInstaller == null) {
- throw new IllegalStateException("Can't obtain calling installer's package.");
- }
-
- // Obtaining array of certificates used for signing the installer package.
- // According to V2/V3 signing schema, the first certificate corresponds to public key
- // in the signing block.
- Signature[] certs = callingInstaller.getSigningDetails().signatures;
- if (certs == null || certs.length == 0 || certs[0] == null) {
- throw new IllegalStateException(
- "Can't obtain calling installer package's certificates.");
- }
- byte[] mainCertificateBytes = certs[0].toByteArray();
-
- synchronized (mLock) {
- assertCallerIsOwnerOrRootLocked();
- assertPreparedAndNotCommittedOrDestroyedLocked("addChecksums");
-
- for (Checksum checksum : checksums) {
- List<CertifiedChecksum> fileChecksums = mChecksums.get(name);
- if (fileChecksums == null) {
- fileChecksums = new ArrayList<>();
- mChecksums.put(name, fileChecksums);
- }
- fileChecksums.add(new CertifiedChecksum(checksum, mainCertificateBytes));
- }
- }
- }
-
- @Override
public void removeSplit(String splitName) {
if (isDataLoaderInstallation()) {
throw new IllegalStateException(
@@ -2232,7 +2155,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
final File targetFile = new File(stageDir, targetName);
- resolveAndStageFileLocked(addedFile, targetFile, null);
+ resolveAndStageFileLocked(addedFile, targetFile);
mResolvedBaseFile = targetFile;
// Populate package name of the apex session
@@ -2251,13 +2174,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
- private static String splitNameToFileName(String splitName) {
- if (splitName == null) {
- return "base";
- }
- return "split_" + splitName;
- }
-
/**
* Validate install by confirming that all application packages are have
* consistent package name, version code, and signing certificates.
@@ -2343,21 +2259,37 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
assertApkConsistentLocked(String.valueOf(addedFile), apk);
// Take this opportunity to enforce uniform naming
- final String fileName = splitNameToFileName(apk.splitName);
- final String targetName = fileName + APK_FILE_EXTENSION;
+ final String targetName;
+ if (apk.splitName == null) {
+ targetName = "base" + APK_FILE_EXTENSION;
+ } else {
+ targetName = "split_" + apk.splitName + APK_FILE_EXTENSION;
+ }
if (!FileUtils.isValidExtFilename(targetName)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Invalid filename: " + targetName);
}
final File targetFile = new File(stageDir, targetName);
- resolveAndStageFileLocked(addedFile, targetFile, apk.splitName);
+ resolveAndStageFileLocked(addedFile, targetFile);
// Base is coming from session
if (apk.splitName == null) {
mResolvedBaseFile = targetFile;
baseApk = apk;
}
+
+ // Validate and add Dex Metadata (.dm).
+ final File dexMetadataFile = DexMetadataHelper.findDexMetadataForFile(addedFile);
+ if (dexMetadataFile != null) {
+ if (!FileUtils.isValidExtFilename(dexMetadataFile.getName())) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Invalid filename: " + dexMetadataFile);
+ }
+ final File targetDexMetadataFile = new File(stageDir,
+ DexMetadataHelper.buildDexMetadataPathForApk(targetName));
+ resolveAndStageFileLocked(dexMetadataFile, targetDexMetadataFile);
+ }
}
if (removeSplitList.size() > 0) {
@@ -2406,20 +2338,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
- if (!mChecksums.isEmpty()) {
- throw new PackageManagerException(
- PackageManager.INSTALL_FAILED_SESSION_INVALID,
- "Invalid checksum name(s): " + String.join(",", mChecksums.keySet()));
- }
-
if (params.mode == SessionParams.MODE_FULL_INSTALL) {
// Full installs must include a base package
if (!stagedSplits.contains(null)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Full install must include a base package");
}
+
} else {
- final ApplicationInfo appInfo = pkgInfo.applicationInfo;
+ ApplicationInfo appInfo = pkgInfo.applicationInfo;
ParseResult<PackageLite> pkgLiteResult = ApkLiteParseUtils.parsePackageLite(
input.reset(), new File(appInfo.getCodePath()), 0);
if (pkgLiteResult.isError()) {
@@ -2438,21 +2365,33 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
assertApkConsistentLocked("Existing base", existingBase);
- // Inherit base if not overridden.
+ // Inherit base if not overridden
if (mResolvedBaseFile == null) {
mResolvedBaseFile = new File(appInfo.getBaseCodePath());
- inheritFileLocked(mResolvedBaseFile);
+ resolveInheritedFileLocked(mResolvedBaseFile);
+ // Inherit the dex metadata if present.
+ final File baseDexMetadataFile =
+ DexMetadataHelper.findDexMetadataForFile(mResolvedBaseFile);
+ if (baseDexMetadataFile != null) {
+ resolveInheritedFileLocked(baseDexMetadataFile);
+ }
baseApk = existingBase;
}
- // Inherit splits if not overridden.
+ // Inherit splits if not overridden
if (!ArrayUtils.isEmpty(existing.splitNames)) {
for (int i = 0; i < existing.splitNames.length; i++) {
final String splitName = existing.splitNames[i];
final File splitFile = new File(existing.splitCodePaths[i]);
final boolean splitRemoved = removeSplitList.contains(splitName);
if (!stagedSplits.contains(splitName) && !splitRemoved) {
- inheritFileLocked(splitFile);
+ resolveInheritedFileLocked(splitFile);
+ // Inherit the dex metadata if present.
+ final File splitDexMetadataFile =
+ DexMetadataHelper.findDexMetadataForFile(splitFile);
+ if (splitDexMetadataFile != null) {
+ resolveInheritedFileLocked(splitDexMetadataFile);
+ }
}
}
}
@@ -2553,15 +2492,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
@GuardedBy("mLock")
- private void stageFileLocked(File origFile, File targetFile)
+ private void resolveAndStageFileLocked(File origFile, File targetFile)
throws PackageManagerException {
mResolvedStagedFiles.add(targetFile);
maybeRenameFile(origFile, targetFile);
- }
- @GuardedBy("mLock")
- private void maybeStageFsveritySignatureLocked(File origFile, File targetFile)
- throws PackageManagerException {
final File originalSignature = new File(
VerityUtils.getFsveritySignatureFilePath(origFile.getPath()));
// Make sure .fsv_sig exists when it should, then resolve and stage it.
@@ -2586,83 +2521,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final File stagedSignature = new File(
VerityUtils.getFsveritySignatureFilePath(targetFile.getPath()));
-
- stageFileLocked(originalSignature, stagedSignature);
+ maybeRenameFile(originalSignature, stagedSignature);
+ mResolvedStagedFiles.add(stagedSignature);
}
@GuardedBy("mLock")
- private void maybeStageDexMetadataLocked(File origFile, File targetFile)
- throws PackageManagerException {
- final File dexMetadataFile = DexMetadataHelper.findDexMetadataForFile(origFile);
- if (dexMetadataFile == null) {
- return;
- }
-
- if (!FileUtils.isValidExtFilename(dexMetadataFile.getName())) {
- throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
- "Invalid filename: " + dexMetadataFile);
- }
- final File targetDexMetadataFile = new File(stageDir,
- DexMetadataHelper.buildDexMetadataPathForApk(targetFile.getName()));
-
- stageFileLocked(dexMetadataFile, targetDexMetadataFile);
- }
-
- private static ApkChecksum[] createApkChecksums(String splitName,
- List<CertifiedChecksum> checksums) {
- ApkChecksum[] result = new ApkChecksum[checksums.size()];
- for (int i = 0, size = checksums.size(); i < size; ++i) {
- CertifiedChecksum checksum = checksums.get(i);
- result[i] = new ApkChecksum(splitName, checksum.getChecksum(),
- checksum.getCertificate());
- }
- return result;
- }
-
- @GuardedBy("mLock")
- private void maybeStageDigestsLocked(File origFile, File targetFile, String splitName)
- throws PackageManagerException {
- final List<CertifiedChecksum> checksums = mChecksums.get(origFile.getName());
- if (checksums == null) {
- return;
- }
- mChecksums.remove(origFile.getName());
-
- if (checksums.isEmpty()) {
- return;
- }
-
- final File targetDigestsFile = new File(stageDir,
- ApkChecksums.buildDigestsPathForApk(targetFile.getName()));
- try {
- ApkChecksums.writeChecksums(targetDigestsFile,
- createApkChecksums(splitName, checksums));
- } catch (CertificateException e) {
- throw new PackageManagerException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING,
- "Failed to encode certificate for " + mPackageName, e);
- } catch (IOException e) {
- throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
- "Failed to store digests for " + mPackageName, e);
- }
-
- stageFileLocked(targetDigestsFile, targetDigestsFile);
- }
-
- @GuardedBy("mLock")
- private void resolveAndStageFileLocked(File origFile, File targetFile, String splitName)
- throws PackageManagerException {
- stageFileLocked(origFile, targetFile);
-
- // Stage fsverity signature if present.
- maybeStageFsveritySignatureLocked(origFile, targetFile);
- // Stage dex metadata (.dm) if present.
- maybeStageDexMetadataLocked(origFile, targetFile);
- // Stage checksums (.digests) if present.
- maybeStageDigestsLocked(origFile, targetFile, splitName);
- }
-
- @GuardedBy("mLock")
- private void inheritFileLocked(File origFile) {
+ private void resolveInheritedFileLocked(File origFile) {
mResolvedInheritedFiles.add(origFile);
// Inherit the fsverity signature file if present.
@@ -2671,17 +2535,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (fsveritySignatureFile.exists()) {
mResolvedInheritedFiles.add(fsveritySignatureFile);
}
- // Inherit the dex metadata if present.
- final File dexMetadataFile =
- DexMetadataHelper.findDexMetadataForFile(origFile);
- if (dexMetadataFile != null) {
- mResolvedInheritedFiles.add(dexMetadataFile);
- }
- // Inherit the digests if present.
- final File digestsFile = ApkChecksums.findDigestsForFile(origFile);
- if (digestsFile != null) {
- mResolvedInheritedFiles.add(digestsFile);
- }
}
@GuardedBy("mLock")
@@ -3938,22 +3791,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
writeByteArrayAttribute(out, ATTR_SIGNATURE, file.getSignature());
out.endTag(null, TAG_SESSION_FILE);
}
-
- for (int i = 0, isize = mChecksums.size(); i < isize; ++i) {
- String fileName = mChecksums.keyAt(i);
- List<CertifiedChecksum> checksums = mChecksums.valueAt(i);
- for (int j = 0, jsize = checksums.size(); j < jsize; ++j) {
- CertifiedChecksum checksum = checksums.get(j);
- out.startTag(null, TAG_SESSION_CHECKSUM);
- writeStringAttribute(out, ATTR_NAME, fileName);
- writeIntAttribute(out, ATTR_CHECKSUM_KIND, checksum.getChecksum().getKind());
- writeByteArrayAttribute(out, ATTR_CHECKSUM_VALUE,
- checksum.getChecksum().getValue());
- writeByteArrayAttribute(out, ATTR_CHECKSUM_CERTIFICATE,
- checksum.getCertificate());
- out.endTag(null, TAG_SESSION_CHECKSUM);
- }
- }
}
out.endTag(null, TAG_SESSION);
@@ -4067,7 +3904,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
int autoRevokePermissionsMode = MODE_DEFAULT;
List<Integer> childSessionIds = new ArrayList<>();
List<InstallationFile> files = new ArrayList<>();
- ArrayMap<String, List<CertifiedChecksum>> checksums = new ArrayMap<>();
int outerDepth = in.getDepth();
int type;
while ((type = in.next()) != XmlPullParser.END_DOCUMENT
@@ -4096,20 +3932,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
readByteArrayAttribute(in, ATTR_METADATA),
readByteArrayAttribute(in, ATTR_SIGNATURE)));
}
- if (TAG_SESSION_CHECKSUM.equals(in.getName())) {
- final String fileName = readStringAttribute(in, ATTR_NAME);
- final CertifiedChecksum certifiedChecksum = new CertifiedChecksum(
- new Checksum(readIntAttribute(in, ATTR_CHECKSUM_KIND, 0),
- readByteArrayAttribute(in, ATTR_CHECKSUM_VALUE)),
- readByteArrayAttribute(in, ATTR_CHECKSUM_CERTIFICATE));
-
- List<CertifiedChecksum> certifiedChecksums = checksums.get(fileName);
- if (certifiedChecksums == null) {
- certifiedChecksums = new ArrayList<>();
- checksums.put(fileName, certifiedChecksums);
- }
- certifiedChecksums.add(certifiedChecksum);
- }
}
if (grantedRuntimePermissions.size() > 0) {
@@ -4142,7 +3964,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
installOriginatingPackageName, installerPackageName, installerAttributionTag);
return new PackageInstallerSession(callback, context, pm, sessionProvider,
installerThread, stagingManager, sessionId, userId, installerUid,
- installSource, params, createdMillis, stageDir, stageCid, fileArray, checksums,
+ installSource, params, createdMillis, stageDir, stageCid, fileArray,
prepared, committed, destroyed, sealed, childSessionIdsArray, parentSessionId,
isReady, isFailed, isApplied, stagedSessionErrorCode, stagedSessionErrorMessage);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 156625597d86..9f78f0f08fd1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -164,7 +164,6 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.AuxiliaryResolveInfo;
import android.content.pm.ChangedPackages;
-import android.content.pm.Checksum;
import android.content.pm.ComponentInfo;
import android.content.pm.DataLoaderType;
import android.content.pm.FallbackCategoryProvider;
@@ -2460,8 +2459,8 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void getChecksums(@NonNull String packageName, boolean includeSplits,
- @Checksum.Kind int optional,
- @Checksum.Kind int required, @Nullable List trustedInstallers,
+ @PackageManager.FileChecksumKind int optional,
+ @PackageManager.FileChecksumKind int required, @Nullable List trustedInstallers,
@NonNull IntentSender statusReceiver, int userId) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(statusReceiver);
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
index 4a6e11bca613..fe429c8823f8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
@@ -176,7 +176,6 @@ public class PackageInstallerSessionTest {
/* stageDir */ mTmpDir,
/* stageCid */ null,
/* files */ null,
- /* checksums */ null,
/* prepared */ true,
/* committed */ true,
/* destroyed */ staged ? true : false,