• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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