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 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 */ 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 */ 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#getSourceInfo 74 */ 75 public abstract int getSource(); 76 77 /** 78 * Modifies the source of the event. 79 * 80 * @param source The new source. 81 * @hide 82 */ 83 public abstract void setSource(int source); 84 85 /** 86 * Copies the event. 87 * 88 * @return A deep copy of the event. 89 * @hide 90 */ 91 public abstract InputEvent copy(); 92 93 /** 94 * Recycles the event. 95 * This method should only be used by the system since applications do not 96 * expect {@link KeyEvent} objects to be recycled, although {@link MotionEvent} 97 * objects are fine. See {@link KeyEvent#recycle()} for details. 98 * @hide 99 */ 100 public void recycle() { 101 if (TRACK_RECYCLED_LOCATION) { 102 if (mRecycledLocation != null) { 103 throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation); 104 } 105 mRecycledLocation = new RuntimeException("Last recycled here"); 106 } else { 107 if (mRecycled) { 108 throw new RuntimeException(toString() + " recycled twice!"); 109 } 110 mRecycled = true; 111 } 112 } 113 114 /** 115 * Conditionally recycled the event if it is appropriate to do so after 116 * dispatching the event to an application. 117 * 118 * If the event is a {@link MotionEvent} then it is recycled. 119 * 120 * If the event is a {@link KeyEvent} then it is NOT recycled, because applications 121 * expect key events to be immutable so once the event has been dispatched to 122 * the application we can no longer recycle it. 123 * @hide 124 */ 125 public void recycleIfNeededAfterDispatch() { 126 recycle(); 127 } 128 129 /** 130 * Reinitializes the event on reuse (after recycling). 131 * @hide 132 */ 133 protected void prepareForReuse() { 134 mRecycled = false; 135 mRecycledLocation = null; 136 mSeq = mNextSeq.getAndIncrement(); 137 } 138 139 /** 140 * Gets a private flag that indicates when the system has detected that this input event 141 * may be inconsistent with respect to the sequence of previously delivered input events, 142 * such as when a key up event is sent but the key was not down or when a pointer 143 * move event is sent but the pointer is not down. 144 * 145 * @return True if this event is tainted. 146 * @hide 147 */ 148 public abstract boolean isTainted(); 149 150 /** 151 * Sets a private flag that indicates when the system has detected that this input event 152 * may be inconsistent with respect to the sequence of previously delivered input events, 153 * such as when a key up event is sent but the key was not down or when a pointer 154 * move event is sent but the pointer is not down. 155 * 156 * @param tainted True if this event is tainted. 157 * @hide 158 */ 159 public abstract void setTainted(boolean tainted); 160 161 /** 162 * Retrieve the time this event occurred, 163 * in the {@link android.os.SystemClock#uptimeMillis} time base. 164 * 165 * @return Returns the time this event occurred, 166 * in the {@link android.os.SystemClock#uptimeMillis} time base. 167 */ 168 public abstract long getEventTime(); 169 170 /** 171 * Retrieve the time this event occurred, 172 * in the {@link android.os.SystemClock#uptimeMillis} time base but with 173 * nanosecond (instead of millisecond) precision. 174 * <p> 175 * The value is in nanosecond precision but it may not have nanosecond accuracy. 176 * </p> 177 * 178 * @return Returns the time this event occurred, 179 * in the {@link android.os.SystemClock#uptimeMillis} time base but with 180 * nanosecond (instead of millisecond) precision. 181 * 182 * @hide 183 */ 184 public abstract long getEventTimeNano(); 185 186 /** 187 * Gets the unique sequence number of this event. 188 * Every input event that is created or received by a process has a 189 * unique sequence number. Moreover, a new sequence number is obtained 190 * each time an event object is recycled. 191 * 192 * Sequence numbers are only guaranteed to be locally unique within a process. 193 * Sequence numbers are not preserved when events are parceled. 194 * 195 * @return The unique sequence number of this event. 196 * @hide 197 */ 198 public int getSequenceNumber() { 199 return mSeq; 200 } 201 202 public int describeContents() { 203 return 0; 204 } 205 206 public static final Parcelable.Creator<InputEvent> CREATOR 207 = new Parcelable.Creator<InputEvent>() { 208 public InputEvent createFromParcel(Parcel in) { 209 int token = in.readInt(); 210 if (token == PARCEL_TOKEN_KEY_EVENT) { 211 return KeyEvent.createFromParcelBody(in); 212 } else if (token == PARCEL_TOKEN_MOTION_EVENT) { 213 return MotionEvent.createFromParcelBody(in); 214 } else { 215 throw new IllegalStateException("Unexpected input event type token in parcel."); 216 } 217 } 218 219 public InputEvent[] newArray(int size) { 220 return new InputEvent[size]; 221 } 222 }; 223 } 224