1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.P; 4 import static org.robolectric.Shadows.shadowOf; 5 6 import android.content.pm.Signature; 7 import android.content.pm.SigningInfo; 8 import android.os.Parcel; 9 import android.os.Parcelable; 10 import org.robolectric.annotation.Implementation; 11 import org.robolectric.annotation.Implements; 12 import org.robolectric.shadow.api.Shadow; 13 import org.robolectric.util.ReflectionHelpers; 14 15 @Implements(value = SigningInfo.class, minSdk = P) 16 public class ShadowSigningInfo { 17 public static final Parcelable.Creator<SigningInfo> CREATOR = 18 new Parcelable.Creator<SigningInfo>() { 19 @Override 20 public SigningInfo createFromParcel(Parcel in) { 21 SigningInfo signingInfo = Shadow.newInstanceOf(SigningInfo.class); 22 shadowOf(signingInfo).setSignatures(in.createTypedArray(Signature.CREATOR)); 23 shadowOf(signingInfo).setPastSigningCertificates(in.createTypedArray(Signature.CREATOR)); 24 return signingInfo; 25 } 26 27 @Override 28 public SigningInfo[] newArray(int size) { 29 return new SigningInfo[size]; 30 } 31 }; 32 33 private Signature[] signatures; 34 private Signature[] pastSigningCertificates; 35 36 /** 37 * Set the current Signatures for this package. If signatures has a size greater than 1, 38 * {@link #hasMultipleSigners} will be true and {@link #getSigningCertificateHistory} will return 39 * null. 40 */ setSignatures(Signature[] signatures)41 public void setSignatures(Signature[] signatures) { 42 this.signatures = signatures; 43 } 44 45 /** 46 * Sets the history of Signatures for this package. 47 */ setPastSigningCertificates(Signature[] pastSigningCertificates)48 public void setPastSigningCertificates(Signature[] pastSigningCertificates) { 49 this.pastSigningCertificates = pastSigningCertificates; 50 } 51 52 @Implementation hasMultipleSigners()53 protected boolean hasMultipleSigners() { 54 return signatures != null && signatures.length > 1; 55 } 56 57 @Implementation hasPastSigningCertificates()58 protected boolean hasPastSigningCertificates() { 59 return signatures != null && pastSigningCertificates != null; 60 } 61 62 @Implementation getSigningCertificateHistory()63 protected Signature[] getSigningCertificateHistory() { 64 if (hasMultipleSigners()) { 65 return null; 66 } else if (!hasPastSigningCertificates()) { 67 // this package is only signed by one signer with no history, return it 68 return signatures; 69 } else { 70 // this package has provided proof of past signing certificates, include them 71 return pastSigningCertificates; 72 } 73 } 74 75 @Implementation getApkContentsSigners()76 protected Signature[] getApkContentsSigners() { 77 return signatures; 78 } 79 80 @Implementation writeToParcel(Parcel parcel, int flags)81 public void writeToParcel(Parcel parcel, int flags) { 82 // Overwrite the CREATOR so that we can simulate reading from parcel. 83 ReflectionHelpers.setStaticField(SigningInfo.class, "CREATOR", CREATOR); 84 85 parcel.writeTypedArray(signatures, flags); 86 parcel.writeTypedArray(pastSigningCertificates, flags); 87 } 88 } 89