| /* |
| * Copyright (C) 2021 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.view.displayhash; |
| |
| import android.annotation.CurrentTimeMillisLong; |
| import android.annotation.NonNull; |
| import android.annotation.SystemApi; |
| import android.graphics.Rect; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| |
| import com.android.internal.util.AnnotationValidations; |
| |
| /** |
| * The DisplayHash used to validate information about what was present on screen. |
| */ |
| public final class DisplayHash implements Parcelable { |
| /** |
| * The timestamp when the hash was generated. |
| */ |
| @CurrentTimeMillisLong |
| private final long mTimeMillis; |
| |
| /** |
| * The bounds of the requested area to generate the hash. This is in window space passed in |
| * by the client. |
| */ |
| @NonNull |
| private final Rect mBoundsInWindow; |
| |
| /** |
| * The selected hash algorithm that generated the image hash. |
| */ |
| @NonNull |
| private final String mHashAlgorithm; |
| |
| /** |
| * The image hash generated when creating the DisplayHash. |
| */ |
| @NonNull |
| private final byte[] mImageHash; |
| |
| /** |
| * The hmac generated by the system and used to verify whether this token was generated by |
| * the system. |
| */ |
| @NonNull |
| private final byte[] mHmac; |
| |
| /** |
| * Creates a new DisplayHash. |
| * |
| * @param timeMillis The timestamp when the hash was generated. |
| * @param boundsInWindow The bounds of the requested area to generate the hash. This is |
| * in window space passed in by the client. |
| * @param hashAlgorithm The selected hash algorithm that generated the image hash. |
| * @param imageHash The image hash generated when creating the DisplayHash. |
| * @param hmac The hmac generated by the system and used to verify whether this |
| * token was generated by |
| * the system. This should only be accessed by a system process. |
| * @hide |
| */ |
| @SystemApi |
| public DisplayHash(@CurrentTimeMillisLong long timeMillis, @NonNull Rect boundsInWindow, |
| @NonNull String hashAlgorithm, @NonNull byte[] imageHash, @NonNull byte[] hmac) { |
| mTimeMillis = timeMillis; |
| mBoundsInWindow = boundsInWindow; |
| AnnotationValidations.validate(NonNull.class, null, mBoundsInWindow); |
| mHashAlgorithm = hashAlgorithm; |
| AnnotationValidations.validate(NonNull.class, null, mHashAlgorithm); |
| mImageHash = imageHash; |
| AnnotationValidations.validate(NonNull.class, null, mImageHash); |
| mHmac = hmac; |
| AnnotationValidations.validate(NonNull.class, null, mHmac); |
| } |
| |
| /** |
| * The timestamp when the hash was generated. |
| * |
| * @hide |
| */ |
| @SystemApi |
| @CurrentTimeMillisLong |
| public long getTimeMillis() { |
| return mTimeMillis; |
| } |
| |
| /** |
| * The bounds of the requested area to to generate the hash. This is in window space passed in |
| * by the client. |
| * |
| * @hide |
| */ |
| @SystemApi |
| @NonNull |
| public Rect getBoundsInWindow() { |
| return mBoundsInWindow; |
| } |
| |
| /** |
| * The selected hash algorithm that generated the image hash. |
| * |
| * @hide |
| */ |
| @SystemApi |
| @NonNull |
| public String getHashAlgorithm() { |
| return mHashAlgorithm; |
| } |
| |
| /** |
| * The image hash generated when creating the DisplayHash. |
| * |
| * @hide |
| */ |
| @SystemApi |
| @NonNull |
| public byte[] getImageHash() { |
| return mImageHash; |
| } |
| |
| /** |
| * The hmac generated by the system and used to verify whether this token was generated by |
| * the system. This should only be accessed by a system process. |
| * |
| * @hide |
| */ |
| @SystemApi |
| @NonNull |
| public byte[] getHmac() { |
| return mHmac; |
| } |
| |
| /** @hide **/ |
| @Override |
| public String toString() { |
| return "DisplayHash { " |
| + "timeMillis = " + mTimeMillis + ", " |
| + "boundsInWindow = " + mBoundsInWindow + ", " |
| + "hashAlgorithm = " + mHashAlgorithm + ", " |
| + "imageHash = " + byteArrayToString(mImageHash) + ", " |
| + "hmac = " + byteArrayToString(mHmac) |
| + " }"; |
| } |
| |
| private String byteArrayToString(byte[] byteArray) { |
| if (byteArray == null) { |
| return "null"; |
| } |
| int iMax = byteArray.length - 1; |
| if (iMax == -1) { |
| return "[]"; |
| } |
| |
| StringBuilder b = new StringBuilder(); |
| b.append('['); |
| for (int i = 0; ; i++) { |
| String formatted = String.format("%02X", byteArray[i] & 0xFF); |
| b.append(formatted); |
| if (i == iMax) { |
| return b.append(']').toString(); |
| } |
| b.append(", "); |
| } |
| } |
| |
| /** @hide **/ |
| @SystemApi |
| @Override |
| public void writeToParcel(@NonNull Parcel dest, int flags) { |
| dest.writeLong(mTimeMillis); |
| dest.writeTypedObject(mBoundsInWindow, flags); |
| dest.writeString(mHashAlgorithm); |
| dest.writeByteArray(mImageHash); |
| dest.writeByteArray(mHmac); |
| } |
| |
| /** @hide **/ |
| @SystemApi |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| private DisplayHash(@NonNull Parcel in) { |
| mTimeMillis = in.readLong(); |
| Rect boundsInWindow = in.readTypedObject(Rect.CREATOR); |
| String hashAlgorithm = in.readString(); |
| byte[] imageHash = in.createByteArray(); |
| byte[] hmac = in.createByteArray(); |
| |
| mBoundsInWindow = boundsInWindow; |
| AnnotationValidations.validate(NonNull.class, null, mBoundsInWindow); |
| mHashAlgorithm = hashAlgorithm; |
| AnnotationValidations.validate(NonNull.class, null, mHashAlgorithm); |
| mImageHash = imageHash; |
| AnnotationValidations.validate(NonNull.class, null, mImageHash); |
| mHmac = hmac; |
| AnnotationValidations.validate(NonNull.class, null, mHmac); |
| } |
| |
| @NonNull |
| public static final Parcelable.Creator<DisplayHash> CREATOR = |
| new Parcelable.Creator<DisplayHash>() { |
| @Override |
| public DisplayHash[] newArray(int size) { |
| return new DisplayHash[size]; |
| } |
| |
| @Override |
| public DisplayHash createFromParcel(@NonNull Parcel in) { |
| return new DisplayHash(in); |
| } |
| }; |
| } |