Loading api/current.txt +13 −1 Original line number Diff line number Diff line Loading @@ -11020,7 +11020,7 @@ package android.content.pm { field public java.lang.String sharedUserId; field public int sharedUserLabel; field public deprecated android.content.pm.Signature[] signatures; field public android.content.pm.Signature[][] signingCertificateHistory; field public android.content.pm.SigningInfo signingInfo; field public java.lang.String[] splitNames; field public int[] splitRevisionCodes; field public deprecated int versionCode; Loading Loading @@ -11648,6 +11648,18 @@ package android.content.pm { field public static final android.os.Parcelable.Creator<android.content.pm.Signature> CREATOR; } public final class SigningInfo implements android.os.Parcelable { ctor public SigningInfo(); ctor public SigningInfo(android.content.pm.SigningInfo); method public int describeContents(); method public android.content.pm.Signature[] getApkContentsSigners(); method public android.content.pm.Signature[] getSigningCertificateHistory(); method public boolean hasMultipleSigners(); method public boolean hasPastSigningCertificates(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.content.pm.SigningInfo> CREATOR; } public final class VersionedPackage implements android.os.Parcelable { ctor public VersionedPackage(java.lang.String, int); ctor public VersionedPackage(java.lang.String, long); core/java/android/content/pm/PackageInfo.java +14 −41 Original line number Diff line number Diff line Loading @@ -244,7 +244,7 @@ public class PackageInfo implements Parcelable { * the first position to be the same across updates. * * <strong>Deprecated</strong> This has been replaced by the * {@link PackageInfo#signingCertificateHistory} field, which takes into * {@link PackageInfo#signingInfo} field, which takes into * account signing certificate rotation. For backwards compatibility in * the event of signing certificate rotation, this will return the oldest * reported signing certificate, so that an application will appear to Loading @@ -256,29 +256,15 @@ public class PackageInfo implements Parcelable { public Signature[] signatures; /** * Array of all signatures arrays read from the package file, potentially * Signing information read from the package file, potentially * including past signing certificates no longer used after signing * certificate rotation. Though signing certificate rotation is only * available for apps with a single signing certificate, this provides an * array of arrays so that packages signed with multiple signing * certificates can still return all signers. This is only filled in if * certificate rotation. This is only filled in if * the flag {@link PackageManager#GET_SIGNING_CERTIFICATES} was set. * * A package must be singed with at least one certificate, which is at * position zero in the array. An application may be signed by multiple * certificates, which would be in the array at position zero in an * indeterminate order. A package may also have a history of certificates * due to signing certificate rotation. In this case, the array will be * populated by a series of single-entry arrays corresponding to a signing * certificate of the package. * * <strong>Note:</strong> Signature ordering is not guaranteed to be * stable which means that a package signed with certificates A and B is * equivalent to being signed with certificates B and A. This means that * in case multiple signatures are reported you cannot assume the one at * the first position will be the same across updates. * Use this field instead of the deprecated {@code signatures} field. * See {@link SigningInfo} for more information on its contents. */ public Signature[][] signingCertificateHistory; public SigningInfo signingInfo; /** * Application specified preferred configuration Loading Loading @@ -476,17 +462,11 @@ public class PackageInfo implements Parcelable { dest.writeBoolean(mOverlayIsStatic); dest.writeInt(compileSdkVersion); dest.writeString(compileSdkVersionCodename); writeSigningCertificateHistoryToParcel(dest, parcelableFlags); } private void writeSigningCertificateHistoryToParcel(Parcel dest, int parcelableFlags) { if (signingCertificateHistory != null) { dest.writeInt(signingCertificateHistory.length); for (int i = 0; i < signingCertificateHistory.length; i++) { dest.writeTypedArray(signingCertificateHistory[i], parcelableFlags); } if (signingInfo != null) { dest.writeInt(1); signingInfo.writeToParcel(dest, parcelableFlags); } else { dest.writeInt(-1); dest.writeInt(0); } } Loading Loading @@ -544,7 +524,10 @@ public class PackageInfo implements Parcelable { mOverlayIsStatic = source.readBoolean(); compileSdkVersion = source.readInt(); compileSdkVersionCodename = source.readString(); readSigningCertificateHistoryFromParcel(source); int hasSigningInfo = source.readInt(); if (hasSigningInfo != 0) { signingInfo = SigningInfo.CREATOR.createFromParcel(source); } // The component lists were flattened with the redundant ApplicationInfo // instances omitted. Distribute the canonical one here as appropriate. Loading @@ -556,16 +539,6 @@ public class PackageInfo implements Parcelable { } } private void readSigningCertificateHistoryFromParcel(Parcel source) { int len = source.readInt(); if (len != -1) { signingCertificateHistory = new Signature[len][]; for (int i = 0; i < len; i++) { signingCertificateHistory[i] = source.createTypedArray(Signature.CREATOR); } } } private void propagateApplicationInfo(ApplicationInfo appInfo, ComponentInfo[] components) { if (components != null) { for (ComponentInfo ci : components) { Loading core/java/android/content/pm/PackageParser.java +5 −15 Original line number Diff line number Diff line Loading @@ -810,21 +810,11 @@ public class PackageParser { // replacement for GET_SIGNATURES if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { if (p.mSigningDetails.hasPastSigningCertificates()) { // Package has included signing certificate rotation information. Convert each // entry to an array int numberOfSigs = p.mSigningDetails.pastSigningCertificates.length; pi.signingCertificateHistory = new Signature[numberOfSigs][]; for (int i = 0; i < numberOfSigs; i++) { pi.signingCertificateHistory[i] = new Signature[] { p.mSigningDetails.pastSigningCertificates[i] }; } } else if (p.mSigningDetails.hasSignatures()) { // otherwise keep old behavior int numberOfSigs = p.mSigningDetails.signatures.length; pi.signingCertificateHistory = new Signature[1][numberOfSigs]; System.arraycopy(p.mSigningDetails.signatures, 0, pi.signingCertificateHistory[0], 0, numberOfSigs); if (p.mSigningDetails != SigningDetails.UNKNOWN) { // only return a valid SigningInfo if there is signing information to report pi.signingInfo = new SigningInfo(p.mSigningDetails); } else { pi.signingInfo = null; } } return pi; Loading core/java/android/content/pm/SigningInfo.java 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.NonNull; import android.os.Parcel; import android.os.Parcelable; /** * Information pertaining to the signing certificates used to sign a package. */ public final class SigningInfo implements Parcelable { @NonNull private final PackageParser.SigningDetails mSigningDetails; public SigningInfo() { mSigningDetails = PackageParser.SigningDetails.UNKNOWN; } /** * @hide only packagemanager should be populating this */ public SigningInfo(PackageParser.SigningDetails signingDetails) { mSigningDetails = new PackageParser.SigningDetails(signingDetails); } public SigningInfo(SigningInfo orig) { mSigningDetails = new PackageParser.SigningDetails(orig.mSigningDetails); } private SigningInfo(Parcel source) { mSigningDetails = PackageParser.SigningDetails.CREATOR.createFromParcel(source); } /** * Although relatively uncommon, packages may be signed by more than one signer, in which case * their identity is viewed as being the set of all signers, not just any one. */ public boolean hasMultipleSigners() { return mSigningDetails.signatures != null && mSigningDetails.signatures.length > 1; } /** * APK Signature Scheme v3 enables packages to provide a proof-of-rotation record that the * platform verifies, and uses, to allow the use of new signing certificates. This is only * available to packages that are not signed by multiple signers. In the event of a change to a * new signing certificate, the package's past signing certificates are presented as well. Any * check of a package's signing certificate should also include a search through its entire * signing history, since it could change to a new signing certificate at any time. */ public boolean hasPastSigningCertificates() { return mSigningDetails.signatures != null && mSigningDetails.pastSigningCertificates != null; } /** * Returns the signing certificates this package has proven it is authorized to use. This * includes both the signing certificate associated with the signer of the package and the past * signing certificates it included as its proof of signing certificate rotation. This method * is the preferred replacement for the {@code GET_SIGNATURES} flag used with {@link * PackageManager#getPackageInfo(String, int)}. When determining if a package is signed by a * desired certificate, the returned array should be checked to determine if it is one of the * entries. * * <note> * This method returns null if the package is signed by multiple signing certificates, as * opposed to being signed by one current signer and also providing the history of past * signing certificates. {@link #hasMultipleSigners()} may be used to determine if this * package is signed by multiple signers. Packages which are signed by multiple signers * cannot change their signing certificates and their {@code Signature} array should be * checked to make sure that every entry matches the looked-for signing certificates. * </note> */ public Signature[] getSigningCertificateHistory() { if (hasMultipleSigners()) { return null; } else if (!hasPastSigningCertificates()) { // this package is only signed by one signer with no history, return it return mSigningDetails.signatures; } else { // this package has provided proof of past signing certificates, include them return mSigningDetails.pastSigningCertificates; } } /** * Returns the signing certificates used to sign the APK contents of this application. Not * including any past signing certificates the package proved it is authorized to use. * <note> * This method should not be used unless {@link #hasMultipleSigners()} returns true, * indicating that {@link #getSigningCertificateHistory()} cannot be used, otherwise {@link * #getSigningCertificateHistory()} should be preferred. * </note> */ public Signature[] getApkContentsSigners() { return mSigningDetails.signatures; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int parcelableFlags) { mSigningDetails.writeToParcel(dest, parcelableFlags); } public static final Parcelable.Creator<SigningInfo> CREATOR = new Parcelable.Creator<SigningInfo>() { @Override public SigningInfo createFromParcel(Parcel source) { return new SigningInfo(source); } @Override public SigningInfo[] newArray(int size) { return new SigningInfo[size]; } }; } services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java +9 −7 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; import android.content.pm.SigningInfo; import android.os.Build; import android.os.ParcelFileDescriptor; import android.util.Slog; Loading Loading @@ -240,12 +241,13 @@ public class PackageManagerBackupAgent extends BackupAgent { PackageManager.GET_SIGNING_CERTIFICATES); homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName()); homeVersion = homeInfo.getLongVersionCode(); Signature[][] signingHistory = homeInfo.signingCertificateHistory; if (signingHistory == null || signingHistory.length == 0) { Slog.e(TAG, "Home app has no signing history"); SigningInfo signingInfo = homeInfo.signingInfo; if (signingInfo == null) { Slog.e(TAG, "Home app has no signing information"); } else { // retrieve the newest sigs to back up Signature[] homeInfoSignatures = signingHistory[signingHistory.length - 1]; // TODO (b/73988180) use entire signing history in case of rollbacks Signature[] homeInfoSignatures = signingInfo.getApkContentsSigners(); homeSigHashes = BackupUtils.hashSignatureArray(homeInfoSignatures); } } catch (NameNotFoundException e) { Loading Loading @@ -334,8 +336,8 @@ public class PackageManagerBackupAgent extends BackupAgent { } } Signature[][] signingHistory = info.signingCertificateHistory; if (signingHistory == null || signingHistory.length == 0) { SigningInfo signingInfo = info.signingInfo; if (signingInfo == null) { Slog.w(TAG, "Not backing up package " + packName + " since it appears to have no signatures."); continue; Loading @@ -358,7 +360,7 @@ public class PackageManagerBackupAgent extends BackupAgent { outputBufferStream.writeInt(info.versionCode); } // retrieve the newest sigs to back up Signature[] infoSignatures = signingHistory[signingHistory.length - 1]; Signature[] infoSignatures = signingInfo.getApkContentsSigners(); writeSignatureHashArray(outputBufferStream, BackupUtils.hashSignatureArray(infoSignatures)); Loading Loading
api/current.txt +13 −1 Original line number Diff line number Diff line Loading @@ -11020,7 +11020,7 @@ package android.content.pm { field public java.lang.String sharedUserId; field public int sharedUserLabel; field public deprecated android.content.pm.Signature[] signatures; field public android.content.pm.Signature[][] signingCertificateHistory; field public android.content.pm.SigningInfo signingInfo; field public java.lang.String[] splitNames; field public int[] splitRevisionCodes; field public deprecated int versionCode; Loading Loading @@ -11648,6 +11648,18 @@ package android.content.pm { field public static final android.os.Parcelable.Creator<android.content.pm.Signature> CREATOR; } public final class SigningInfo implements android.os.Parcelable { ctor public SigningInfo(); ctor public SigningInfo(android.content.pm.SigningInfo); method public int describeContents(); method public android.content.pm.Signature[] getApkContentsSigners(); method public android.content.pm.Signature[] getSigningCertificateHistory(); method public boolean hasMultipleSigners(); method public boolean hasPastSigningCertificates(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.content.pm.SigningInfo> CREATOR; } public final class VersionedPackage implements android.os.Parcelable { ctor public VersionedPackage(java.lang.String, int); ctor public VersionedPackage(java.lang.String, long);
core/java/android/content/pm/PackageInfo.java +14 −41 Original line number Diff line number Diff line Loading @@ -244,7 +244,7 @@ public class PackageInfo implements Parcelable { * the first position to be the same across updates. * * <strong>Deprecated</strong> This has been replaced by the * {@link PackageInfo#signingCertificateHistory} field, which takes into * {@link PackageInfo#signingInfo} field, which takes into * account signing certificate rotation. For backwards compatibility in * the event of signing certificate rotation, this will return the oldest * reported signing certificate, so that an application will appear to Loading @@ -256,29 +256,15 @@ public class PackageInfo implements Parcelable { public Signature[] signatures; /** * Array of all signatures arrays read from the package file, potentially * Signing information read from the package file, potentially * including past signing certificates no longer used after signing * certificate rotation. Though signing certificate rotation is only * available for apps with a single signing certificate, this provides an * array of arrays so that packages signed with multiple signing * certificates can still return all signers. This is only filled in if * certificate rotation. This is only filled in if * the flag {@link PackageManager#GET_SIGNING_CERTIFICATES} was set. * * A package must be singed with at least one certificate, which is at * position zero in the array. An application may be signed by multiple * certificates, which would be in the array at position zero in an * indeterminate order. A package may also have a history of certificates * due to signing certificate rotation. In this case, the array will be * populated by a series of single-entry arrays corresponding to a signing * certificate of the package. * * <strong>Note:</strong> Signature ordering is not guaranteed to be * stable which means that a package signed with certificates A and B is * equivalent to being signed with certificates B and A. This means that * in case multiple signatures are reported you cannot assume the one at * the first position will be the same across updates. * Use this field instead of the deprecated {@code signatures} field. * See {@link SigningInfo} for more information on its contents. */ public Signature[][] signingCertificateHistory; public SigningInfo signingInfo; /** * Application specified preferred configuration Loading Loading @@ -476,17 +462,11 @@ public class PackageInfo implements Parcelable { dest.writeBoolean(mOverlayIsStatic); dest.writeInt(compileSdkVersion); dest.writeString(compileSdkVersionCodename); writeSigningCertificateHistoryToParcel(dest, parcelableFlags); } private void writeSigningCertificateHistoryToParcel(Parcel dest, int parcelableFlags) { if (signingCertificateHistory != null) { dest.writeInt(signingCertificateHistory.length); for (int i = 0; i < signingCertificateHistory.length; i++) { dest.writeTypedArray(signingCertificateHistory[i], parcelableFlags); } if (signingInfo != null) { dest.writeInt(1); signingInfo.writeToParcel(dest, parcelableFlags); } else { dest.writeInt(-1); dest.writeInt(0); } } Loading Loading @@ -544,7 +524,10 @@ public class PackageInfo implements Parcelable { mOverlayIsStatic = source.readBoolean(); compileSdkVersion = source.readInt(); compileSdkVersionCodename = source.readString(); readSigningCertificateHistoryFromParcel(source); int hasSigningInfo = source.readInt(); if (hasSigningInfo != 0) { signingInfo = SigningInfo.CREATOR.createFromParcel(source); } // The component lists were flattened with the redundant ApplicationInfo // instances omitted. Distribute the canonical one here as appropriate. Loading @@ -556,16 +539,6 @@ public class PackageInfo implements Parcelable { } } private void readSigningCertificateHistoryFromParcel(Parcel source) { int len = source.readInt(); if (len != -1) { signingCertificateHistory = new Signature[len][]; for (int i = 0; i < len; i++) { signingCertificateHistory[i] = source.createTypedArray(Signature.CREATOR); } } } private void propagateApplicationInfo(ApplicationInfo appInfo, ComponentInfo[] components) { if (components != null) { for (ComponentInfo ci : components) { Loading
core/java/android/content/pm/PackageParser.java +5 −15 Original line number Diff line number Diff line Loading @@ -810,21 +810,11 @@ public class PackageParser { // replacement for GET_SIGNATURES if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { if (p.mSigningDetails.hasPastSigningCertificates()) { // Package has included signing certificate rotation information. Convert each // entry to an array int numberOfSigs = p.mSigningDetails.pastSigningCertificates.length; pi.signingCertificateHistory = new Signature[numberOfSigs][]; for (int i = 0; i < numberOfSigs; i++) { pi.signingCertificateHistory[i] = new Signature[] { p.mSigningDetails.pastSigningCertificates[i] }; } } else if (p.mSigningDetails.hasSignatures()) { // otherwise keep old behavior int numberOfSigs = p.mSigningDetails.signatures.length; pi.signingCertificateHistory = new Signature[1][numberOfSigs]; System.arraycopy(p.mSigningDetails.signatures, 0, pi.signingCertificateHistory[0], 0, numberOfSigs); if (p.mSigningDetails != SigningDetails.UNKNOWN) { // only return a valid SigningInfo if there is signing information to report pi.signingInfo = new SigningInfo(p.mSigningDetails); } else { pi.signingInfo = null; } } return pi; Loading
core/java/android/content/pm/SigningInfo.java 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.NonNull; import android.os.Parcel; import android.os.Parcelable; /** * Information pertaining to the signing certificates used to sign a package. */ public final class SigningInfo implements Parcelable { @NonNull private final PackageParser.SigningDetails mSigningDetails; public SigningInfo() { mSigningDetails = PackageParser.SigningDetails.UNKNOWN; } /** * @hide only packagemanager should be populating this */ public SigningInfo(PackageParser.SigningDetails signingDetails) { mSigningDetails = new PackageParser.SigningDetails(signingDetails); } public SigningInfo(SigningInfo orig) { mSigningDetails = new PackageParser.SigningDetails(orig.mSigningDetails); } private SigningInfo(Parcel source) { mSigningDetails = PackageParser.SigningDetails.CREATOR.createFromParcel(source); } /** * Although relatively uncommon, packages may be signed by more than one signer, in which case * their identity is viewed as being the set of all signers, not just any one. */ public boolean hasMultipleSigners() { return mSigningDetails.signatures != null && mSigningDetails.signatures.length > 1; } /** * APK Signature Scheme v3 enables packages to provide a proof-of-rotation record that the * platform verifies, and uses, to allow the use of new signing certificates. This is only * available to packages that are not signed by multiple signers. In the event of a change to a * new signing certificate, the package's past signing certificates are presented as well. Any * check of a package's signing certificate should also include a search through its entire * signing history, since it could change to a new signing certificate at any time. */ public boolean hasPastSigningCertificates() { return mSigningDetails.signatures != null && mSigningDetails.pastSigningCertificates != null; } /** * Returns the signing certificates this package has proven it is authorized to use. This * includes both the signing certificate associated with the signer of the package and the past * signing certificates it included as its proof of signing certificate rotation. This method * is the preferred replacement for the {@code GET_SIGNATURES} flag used with {@link * PackageManager#getPackageInfo(String, int)}. When determining if a package is signed by a * desired certificate, the returned array should be checked to determine if it is one of the * entries. * * <note> * This method returns null if the package is signed by multiple signing certificates, as * opposed to being signed by one current signer and also providing the history of past * signing certificates. {@link #hasMultipleSigners()} may be used to determine if this * package is signed by multiple signers. Packages which are signed by multiple signers * cannot change their signing certificates and their {@code Signature} array should be * checked to make sure that every entry matches the looked-for signing certificates. * </note> */ public Signature[] getSigningCertificateHistory() { if (hasMultipleSigners()) { return null; } else if (!hasPastSigningCertificates()) { // this package is only signed by one signer with no history, return it return mSigningDetails.signatures; } else { // this package has provided proof of past signing certificates, include them return mSigningDetails.pastSigningCertificates; } } /** * Returns the signing certificates used to sign the APK contents of this application. Not * including any past signing certificates the package proved it is authorized to use. * <note> * This method should not be used unless {@link #hasMultipleSigners()} returns true, * indicating that {@link #getSigningCertificateHistory()} cannot be used, otherwise {@link * #getSigningCertificateHistory()} should be preferred. * </note> */ public Signature[] getApkContentsSigners() { return mSigningDetails.signatures; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int parcelableFlags) { mSigningDetails.writeToParcel(dest, parcelableFlags); } public static final Parcelable.Creator<SigningInfo> CREATOR = new Parcelable.Creator<SigningInfo>() { @Override public SigningInfo createFromParcel(Parcel source) { return new SigningInfo(source); } @Override public SigningInfo[] newArray(int size) { return new SigningInfo[size]; } }; }
services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java +9 −7 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; import android.content.pm.SigningInfo; import android.os.Build; import android.os.ParcelFileDescriptor; import android.util.Slog; Loading Loading @@ -240,12 +241,13 @@ public class PackageManagerBackupAgent extends BackupAgent { PackageManager.GET_SIGNING_CERTIFICATES); homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName()); homeVersion = homeInfo.getLongVersionCode(); Signature[][] signingHistory = homeInfo.signingCertificateHistory; if (signingHistory == null || signingHistory.length == 0) { Slog.e(TAG, "Home app has no signing history"); SigningInfo signingInfo = homeInfo.signingInfo; if (signingInfo == null) { Slog.e(TAG, "Home app has no signing information"); } else { // retrieve the newest sigs to back up Signature[] homeInfoSignatures = signingHistory[signingHistory.length - 1]; // TODO (b/73988180) use entire signing history in case of rollbacks Signature[] homeInfoSignatures = signingInfo.getApkContentsSigners(); homeSigHashes = BackupUtils.hashSignatureArray(homeInfoSignatures); } } catch (NameNotFoundException e) { Loading Loading @@ -334,8 +336,8 @@ public class PackageManagerBackupAgent extends BackupAgent { } } Signature[][] signingHistory = info.signingCertificateHistory; if (signingHistory == null || signingHistory.length == 0) { SigningInfo signingInfo = info.signingInfo; if (signingInfo == null) { Slog.w(TAG, "Not backing up package " + packName + " since it appears to have no signatures."); continue; Loading @@ -358,7 +360,7 @@ public class PackageManagerBackupAgent extends BackupAgent { outputBufferStream.writeInt(info.versionCode); } // retrieve the newest sigs to back up Signature[] infoSignatures = signingHistory[signingHistory.length - 1]; Signature[] infoSignatures = signingInfo.getApkContentsSigners(); writeSignatureHashArray(outputBufferStream, BackupUtils.hashSignatureArray(infoSignatures)); Loading