1 /*
2  * Copyright (C) 2010 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 android.compat.annotation.UnsupportedAppUsage;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 
23 import java.util.concurrent.atomic.AtomicInteger;
24 
25 /**
26  * Common base class for input events.
27  */
28 public abstract class InputEvent implements Parcelable {
29     /** @hide */
30     protected static final int PARCEL_TOKEN_MOTION_EVENT = 1;
31     /** @hide */
32     protected static final int PARCEL_TOKEN_KEY_EVENT = 2;
33 
34     // Next sequence number.
35     private static final AtomicInteger mNextSeq = new AtomicInteger();
36 
37     /** @hide */
38     protected int mSeq;
39 
40     /** @hide */
41     protected boolean mRecycled;
42 
43     private static final boolean TRACK_RECYCLED_LOCATION = false;
44     private RuntimeException mRecycledLocation;
45 
InputEvent()46     /*package*/ InputEvent() {
47         mSeq = mNextSeq.getAndIncrement();
48     }
49 
50     /**
51      * Gets the id for the device that this event came from.  An id of
52      * zero indicates that the event didn't come from a physical device
53      * and maps to the default keymap.  The other numbers are arbitrary and
54      * you shouldn't depend on the values.
55      *
56      * @return The device id.
57      * @see InputDevice#getDevice
58      */
getDeviceId()59     public abstract int getDeviceId();
60 
61     /**
62      * Gets the device that this event came from.
63      *
64      * @return The device, or null if unknown.
65      */
getDevice()66     public final InputDevice getDevice() {
67         return InputDevice.getDevice(getDeviceId());
68     }
69 
70     /**
71      * Gets the source of the event.
72      *
73      * @return The event source or {@link InputDevice#SOURCE_UNKNOWN} if unknown.
74      * @see InputDevice#getSources
75      */
getSource()76     public abstract int getSource();
77 
78     /**
79      * Modifies the source of the event.
80      *
81      * @param source The new source.
82      * @hide
83      */
setSource(int source)84     public abstract void setSource(int source);
85 
86     /**
87      * Determines whether the event is from the given source.
88      *
89      * @param source The input source to check against. This can be a specific device type, such as
90      * {@link InputDevice#SOURCE_TOUCH_NAVIGATION}, or a more generic device class, such as
91      * {@link InputDevice#SOURCE_CLASS_POINTER}.
92      * @return Whether the event is from the given source.
93      */
isFromSource(int source)94     public boolean isFromSource(int source) {
95         return (getSource() & source) == source;
96     }
97 
98     /**
99      * Gets the display id of the event.
100      * @return The display id associated with the event.
101      * @hide
102      */
getDisplayId()103     public abstract int getDisplayId();
104 
105     /**
106      * Modifies the display id associated with the event
107      * @param displayId
108      * @hide
109      */
setDisplayId(int displayId)110     public abstract void setDisplayId(int displayId);
111     /**
112      * Copies the event.
113      *
114      * @return A deep copy of the event.
115      * @hide
116      */
copy()117     public abstract InputEvent copy();
118 
119     /**
120      * Recycles the event.
121      * This method should only be used by the system since applications do not
122      * expect {@link KeyEvent} objects to be recycled, although {@link MotionEvent}
123      * objects are fine.  See {@link KeyEvent#recycle()} for details.
124      * @hide
125      */
recycle()126     public void recycle() {
127         if (TRACK_RECYCLED_LOCATION) {
128             if (mRecycledLocation != null) {
129                 throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
130             }
131             mRecycledLocation = new RuntimeException("Last recycled here");
132         } else {
133             if (mRecycled) {
134                 throw new RuntimeException(toString() + " recycled twice!");
135             }
136             mRecycled = true;
137         }
138     }
139 
140     /**
141      * Conditionally recycled the event if it is appropriate to do so after
142      * dispatching the event to an application.
143      *
144      * If the event is a {@link MotionEvent} then it is recycled.
145      *
146      * If the event is a {@link KeyEvent} then it is NOT recycled, because applications
147      * expect key events to be immutable so once the event has been dispatched to
148      * the application we can no longer recycle it.
149      * @hide
150      */
recycleIfNeededAfterDispatch()151     public void recycleIfNeededAfterDispatch() {
152         recycle();
153     }
154 
155     /**
156      * Reinitializes the event on reuse (after recycling).
157      * @hide
158      */
prepareForReuse()159     protected void prepareForReuse() {
160         mRecycled = false;
161         mRecycledLocation = null;
162         mSeq = mNextSeq.getAndIncrement();
163     }
164 
165     /**
166      * Gets a private flag that indicates when the system has detected that this input event
167      * may be inconsistent with respect to the sequence of previously delivered input events,
168      * such as when a key up event is sent but the key was not down or when a pointer
169      * move event is sent but the pointer is not down.
170      *
171      * @return True if this event is tainted.
172      * @hide
173      */
isTainted()174     public abstract boolean isTainted();
175 
176     /**
177      * Sets a private flag that indicates when the system has detected that this input event
178      * may be inconsistent with respect to the sequence of previously delivered input events,
179      * such as when a key up event is sent but the key was not down or when a pointer
180      * move event is sent but the pointer is not down.
181      *
182      * @param tainted True if this event is tainted.
183      * @hide
184      */
setTainted(boolean tainted)185     public abstract void setTainted(boolean tainted);
186 
187     /**
188      * Retrieve the time this event occurred,
189      * in the {@link android.os.SystemClock#uptimeMillis} time base.
190      *
191      * @return Returns the time this event occurred,
192      * in the {@link android.os.SystemClock#uptimeMillis} time base.
193      */
getEventTime()194     public abstract long getEventTime();
195 
196     /**
197      * Retrieve the time this event occurred,
198      * in the {@link android.os.SystemClock#uptimeMillis} time base but with
199      * nanosecond (instead of millisecond) precision.
200      * <p>
201      * The value is in nanosecond precision but it may not have nanosecond accuracy.
202      * </p>
203      *
204      * @return Returns the time this event occurred,
205      * in the {@link android.os.SystemClock#uptimeMillis} time base but with
206      * nanosecond (instead of millisecond) precision.
207      *
208      * @hide
209      */
getEventTimeNano()210     public abstract long getEventTimeNano();
211 
212     /**
213      * Marks the input event as being canceled.
214      *
215      * @hide
216      */
cancel()217     public abstract void cancel();
218 
219     /**
220      * Gets the unique sequence number of this event.
221      * Every input event that is created or received by a process has a
222      * unique sequence number.  Moreover, a new sequence number is obtained
223      * each time an event object is recycled.
224      *
225      * Sequence numbers are only guaranteed to be locally unique within a process.
226      * Sequence numbers are not preserved when events are parceled.
227      *
228      * @return The unique sequence number of this event.
229      * @hide
230      */
231     @UnsupportedAppUsage
getSequenceNumber()232     public int getSequenceNumber() {
233         return mSeq;
234     }
235 
describeContents()236     public int describeContents() {
237         return 0;
238     }
239 
240     public static final @android.annotation.NonNull Parcelable.Creator<InputEvent> CREATOR
241             = new Parcelable.Creator<InputEvent>() {
242         public InputEvent createFromParcel(Parcel in) {
243             int token = in.readInt();
244             if (token == PARCEL_TOKEN_KEY_EVENT) {
245                 return KeyEvent.createFromParcelBody(in);
246             } else if (token == PARCEL_TOKEN_MOTION_EVENT) {
247                 return MotionEvent.createFromParcelBody(in);
248             } else {
249                 throw new IllegalStateException("Unexpected input event type token in parcel.");
250             }
251         }
252 
253         public InputEvent[] newArray(int size) {
254             return new InputEvent[size];
255         }
256     };
257 }
258