Home | History | Annotate | Download | only in pm
      1 package android.content.pm;
      2 
      3 import android.os.Parcel;
      4 import android.os.Parcelable;
      5 import android.util.Base64;
      6 
      7 import java.util.Arrays;
      8 import java.util.jar.Attributes;
      9 
     10 /**
     11  * Represents the manifest digest for a package. This is suitable for comparison
     12  * of two packages to know whether the manifests are identical.
     13  *
     14  * @hide
     15  */
     16 public class ManifestDigest implements Parcelable {
     17     /** The digest of the manifest in our preferred order. */
     18     private final byte[] mDigest;
     19 
     20     /** Digest field names to look for in preferred order. */
     21     private static final String[] DIGEST_TYPES = {
     22             "SHA1-Digest", "SHA-Digest", "MD5-Digest",
     23     };
     24 
     25     /** What we print out first when toString() is called. */
     26     private static final String TO_STRING_PREFIX = "ManifestDigest {mDigest=";
     27 
     28     ManifestDigest(byte[] digest) {
     29         mDigest = digest;
     30     }
     31 
     32     private ManifestDigest(Parcel source) {
     33         mDigest = source.createByteArray();
     34     }
     35 
     36     static ManifestDigest fromAttributes(Attributes attributes) {
     37         if (attributes == null) {
     38             return null;
     39         }
     40 
     41         String encodedDigest = null;
     42 
     43         for (int i = 0; i < DIGEST_TYPES.length; i++) {
     44             final String value = attributes.getValue(DIGEST_TYPES[i]);
     45             if (value != null) {
     46                 encodedDigest = value;
     47                 break;
     48             }
     49         }
     50 
     51         if (encodedDigest == null) {
     52             return null;
     53         }
     54 
     55         final byte[] digest = Base64.decode(encodedDigest, Base64.DEFAULT);
     56         return new ManifestDigest(digest);
     57     }
     58 
     59     @Override
     60     public int describeContents() {
     61         return 0;
     62     }
     63 
     64     @Override
     65     public boolean equals(Object o) {
     66         if (!(o instanceof ManifestDigest)) {
     67             return false;
     68         }
     69 
     70         final ManifestDigest other = (ManifestDigest) o;
     71 
     72         return this == other || Arrays.equals(mDigest, other.mDigest);
     73     }
     74 
     75     @Override
     76     public int hashCode() {
     77         return Arrays.hashCode(mDigest);
     78     }
     79 
     80     @Override
     81     public String toString() {
     82         final StringBuilder sb = new StringBuilder(TO_STRING_PREFIX.length()
     83                 + (mDigest.length * 3) + 1);
     84 
     85         sb.append(TO_STRING_PREFIX);
     86 
     87         final int N = mDigest.length;
     88         for (int i = 0; i < N; i++) {
     89             final byte b = mDigest[i];
     90             IntegralToString.appendByteAsHex(sb, b, false);
     91             sb.append(',');
     92         }
     93         sb.append('}');
     94 
     95         return sb.toString();
     96     }
     97 
     98     @Override
     99     public void writeToParcel(Parcel dest, int flags) {
    100         dest.writeByteArray(mDigest);
    101     }
    102 
    103     public static final Parcelable.Creator<ManifestDigest> CREATOR
    104             = new Parcelable.Creator<ManifestDigest>() {
    105         public ManifestDigest createFromParcel(Parcel source) {
    106             return new ManifestDigest(source);
    107         }
    108 
    109         public ManifestDigest[] newArray(int size) {
    110             return new ManifestDigest[size];
    111         }
    112     };
    113 
    114 }