1package android.content.pm; 2 3import android.os.Parcel; 4import android.os.Parcelable; 5import android.util.Base64; 6 7import java.util.Arrays; 8import 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 */ 16public 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}