Home | History | Annotate | Download | only in view
      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.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 
     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      */
     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      */
     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      */
     76     public abstract int getSource();
     77 
     78     /**
     79      * Modifies the source of the event.
     80      *
     81      * @param source The new source.
     82      * @hide
     83      */
     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      */
     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      */
    103     public abstract int getDisplayId();
    104 
    105     /**
    106      * Modifies the display id associated with the event
    107      * @param displayId
    108      * @hide
    109      */
    110     public abstract void setDisplayId(int displayId);
    111     /**
    112      * Copies the event.
    113      *
    114      * @return A deep copy of the event.
    115      * @hide
    116      */
    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      */
    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      */
    151     public void recycleIfNeededAfterDispatch() {
    152         recycle();
    153     }
    154 
    155     /**
    156      * Reinitializes the event on reuse (after recycling).
    157      * @hide
    158      */
    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      */
    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      */
    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      */
    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      */
    210     public abstract long getEventTimeNano();
    211 
    212     /**
    213      * Marks the input event as being canceled.
    214      *
    215      * @hide
    216      */
    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
    232     public int getSequenceNumber() {
    233         return mSeq;
    234     }
    235 
    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