1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view; 18 19 import static java.lang.annotation.RetentionPolicy.SOURCE; 20 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.SuppressLint; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 27 import java.lang.annotation.Retention; 28 29 30 /** 31 * Base class for verified events. 32 * Verified events contain the subset of an InputEvent that the system can verify. 33 * Data contained inside VerifiedInputEvent's should be considered trusted and contain only 34 * the original event data that first came from the system. 35 * 36 * @see android.hardware.input.InputManager#verifyInputEvent(InputEvent) 37 */ 38 @SuppressLint("ParcelNotFinal") 39 public abstract class VerifiedInputEvent implements Parcelable { 40 private static final String TAG = "VerifiedInputEvent"; 41 42 /** @hide */ 43 protected static final int VERIFIED_KEY = 1; 44 /** @hide */ 45 protected static final int VERIFIED_MOTION = 2; 46 47 /** @hide */ 48 @Retention(SOURCE) 49 @IntDef(prefix = "VERIFIED", value = {VERIFIED_KEY, VERIFIED_MOTION}) 50 public @interface VerifiedInputEventType {}; 51 52 @VerifiedInputEventType 53 private int mType; 54 55 private int mDeviceId; 56 private long mEventTimeNanos; 57 private int mSource; 58 private int mDisplayId; 59 60 /** @hide */ VerifiedInputEvent(int type, int deviceId, long eventTimeNanos, int source, int displayId)61 protected VerifiedInputEvent(int type, int deviceId, long eventTimeNanos, int source, 62 int displayId) { 63 mType = type; 64 mDeviceId = deviceId; 65 mEventTimeNanos = eventTimeNanos; 66 mSource = source; 67 mDisplayId = displayId; 68 } 69 /** @hide */ VerifiedInputEvent(@onNull Parcel in, int expectedType)70 protected VerifiedInputEvent(@NonNull Parcel in, int expectedType) { 71 mType = in.readInt(); 72 if (mType != expectedType) { 73 throw new IllegalArgumentException("Unexpected input event type token in parcel."); 74 } 75 mDeviceId = in.readInt(); 76 mEventTimeNanos = in.readLong(); 77 mSource = in.readInt(); 78 mDisplayId = in.readInt(); 79 } 80 81 /** 82 * Get the id of the device that generated this event. 83 * 84 * @see InputEvent#getDeviceId() 85 */ getDeviceId()86 public int getDeviceId() { 87 return mDeviceId; 88 } 89 90 /** 91 * Get the time this event occurred, in the {@link android.os.SystemClock#uptimeMillis()} 92 * time base. 93 * 94 * @see InputEvent#getEventTime() 95 */ 96 @SuppressLint("MethodNameUnits") getEventTimeNanos()97 public long getEventTimeNanos() { 98 return mEventTimeNanos; 99 } 100 101 /** 102 * Get the source of the event. 103 * 104 * @see InputEvent#getSource() 105 */ getSource()106 public int getSource() { 107 return mSource; 108 } 109 110 /** 111 * Get the display id that is associated with this event. 112 * 113 * @see Display#getDisplayId() 114 */ getDisplayId()115 public int getDisplayId() { 116 return mDisplayId; 117 } 118 119 /** {@inheritDoc} */ 120 @Override writeToParcel(@onNull Parcel dest, int flags)121 public void writeToParcel(@NonNull Parcel dest, int flags) { 122 dest.writeInt(mType); 123 dest.writeInt(mDeviceId); 124 dest.writeLong(mEventTimeNanos); 125 dest.writeInt(mSource); 126 dest.writeInt(mDisplayId); 127 } 128 129 /** {@inheritDoc} */ 130 @Override describeContents()131 public int describeContents() { 132 return 0; 133 } 134 peekInt(@onNull Parcel parcel)135 private static int peekInt(@NonNull Parcel parcel) { 136 final int initialDataPosition = parcel.dataPosition(); 137 int data = parcel.readInt(); 138 parcel.setDataPosition(initialDataPosition); 139 return data; 140 } 141 142 public static final @NonNull Parcelable.Creator<VerifiedInputEvent> CREATOR = 143 new Parcelable.Creator<VerifiedInputEvent>() { 144 @Override 145 public VerifiedInputEvent[] newArray(int size) { 146 return new VerifiedInputEvent[size]; 147 } 148 149 @Override 150 public VerifiedInputEvent createFromParcel(@NonNull Parcel in) { 151 final int type = peekInt(in); 152 if (type == VERIFIED_KEY) { 153 return VerifiedKeyEvent.CREATOR.createFromParcel(in); 154 } else if (type == VERIFIED_MOTION) { 155 return VerifiedMotionEvent.CREATOR.createFromParcel(in); 156 } 157 throw new IllegalArgumentException("Unexpected input event type in parcel."); 158 } 159 }; 160 } 161