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