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, {@link 38 * #hasMultipleSigners} will be true and {@link #getSigningCertificateHistory} will return null. 39 */ setSignatures(Signature[] signatures)40 public void setSignatures(Signature[] signatures) { 41 this.signatures = signatures; 42 } 43 44 /** Sets the history of Signatures for this package. */ setPastSigningCertificates(Signature[] pastSigningCertificates)45 public void setPastSigningCertificates(Signature[] pastSigningCertificates) { 46 this.pastSigningCertificates = pastSigningCertificates; 47 } 48 49 @Implementation hasMultipleSigners()50 protected boolean hasMultipleSigners() { 51 return signatures != null && signatures.length > 1; 52 } 53 54 @Implementation hasPastSigningCertificates()55 protected boolean hasPastSigningCertificates() { 56 return signatures != null && pastSigningCertificates != null; 57 } 58 59 @Implementation getSigningCertificateHistory()60 protected Signature[] getSigningCertificateHistory() { 61 if (hasMultipleSigners()) { 62 return null; 63 } else if (!hasPastSigningCertificates()) { 64 // this package is only signed by one signer with no history, return it 65 return signatures; 66 } else { 67 // this package has provided proof of past signing certificates, include them 68 return pastSigningCertificates; 69 } 70 } 71 72 @Implementation getApkContentsSigners()73 protected Signature[] getApkContentsSigners() { 74 return signatures; 75 } 76 77 @Implementation writeToParcel(Parcel parcel, int flags)78 public void writeToParcel(Parcel parcel, int flags) { 79 // Overwrite the CREATOR so that we can simulate reading from parcel. 80 ReflectionHelpers.setStaticField(SigningInfo.class, "CREATOR", CREATOR); 81 82 parcel.writeTypedArray(signatures, flags); 83 parcel.writeTypedArray(pastSigningCertificates, flags); 84 } 85 } 86