• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
236     /**
237      * Gets the ID of this event. This is generated when an event is created and preserved until its
238      * last stage. It won't change just because the event crosses process boundary, but should
239      * change when making a copy with modifications.
240      * <p>
241      * To avoid exposing app usage to other processes this ID is generated from a CSPRNG. Therefore
242      * there isn't 100% guarantee on the uniqueness of this ID, though the chance of ID collisions
243      * is considerably low. The rule of thumb is not to rely on the uniqueness for production logic,
244      * but a good source for tracking an event (e.g. logging and profiling).
245      *
246      * @return The ID of this event.
247      * @hide
248      */
getId()249     public abstract int getId();
250 
describeContents()251     public int describeContents() {
252         return 0;
253     }
254 
255     public static final @android.annotation.NonNull Parcelable.Creator<InputEvent> CREATOR
256             = new Parcelable.Creator<InputEvent>() {
257         public InputEvent createFromParcel(Parcel in) {
258             int token = in.readInt();
259             if (token == PARCEL_TOKEN_KEY_EVENT) {
260                 return KeyEvent.createFromParcelBody(in);
261             } else if (token == PARCEL_TOKEN_MOTION_EVENT) {
262                 return MotionEvent.createFromParcelBody(in);
263             } else {
264                 throw new IllegalStateException("Unexpected input event type token in parcel.");
265             }
266         }
267 
268         public InputEvent[] newArray(int size) {
269             return new InputEvent[size];
270         }
271     };
272 }
273