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