|  | /* | 
|  | * Copyright (C) 2020 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | package android.view; | 
|  |  | 
|  | import static java.lang.annotation.RetentionPolicy.SOURCE; | 
|  |  | 
|  | import android.annotation.IntDef; | 
|  | import android.annotation.NonNull; | 
|  | import android.annotation.Nullable; | 
|  | import android.annotation.SuppressLint; | 
|  | import android.os.Parcel; | 
|  | import android.os.Parcelable; | 
|  |  | 
|  | import java.lang.annotation.Retention; | 
|  |  | 
|  |  | 
|  | /** | 
|  | * Base class for verified events. | 
|  | * Verified events contain the subset of an InputEvent that the system can verify. | 
|  | * Data contained inside VerifiedInputEvent's should be considered trusted and contain only | 
|  | * the original event data that first came from the system. | 
|  | * | 
|  | * @see android.hardware.input.InputManager#verifyInputEvent(InputEvent) | 
|  | */ | 
|  | @SuppressLint("ParcelNotFinal") | 
|  | public abstract class VerifiedInputEvent implements Parcelable { | 
|  | private static final String TAG = "VerifiedInputEvent"; | 
|  |  | 
|  | /** @hide */ | 
|  | protected static final int VERIFIED_KEY = 1; | 
|  | /** @hide */ | 
|  | protected static final int VERIFIED_MOTION = 2; | 
|  |  | 
|  | /** @hide */ | 
|  | @Retention(SOURCE) | 
|  | @IntDef(prefix = "VERIFIED", value = {VERIFIED_KEY, VERIFIED_MOTION}) | 
|  | public @interface VerifiedInputEventType {}; | 
|  |  | 
|  | @VerifiedInputEventType | 
|  | private int mType; | 
|  |  | 
|  | private int mDeviceId; | 
|  | private long mEventTimeNanos; | 
|  | private int mSource; | 
|  | private int mDisplayId; | 
|  |  | 
|  | /** @hide */ | 
|  | protected VerifiedInputEvent(int type, int deviceId, long eventTimeNanos, int source, | 
|  | int displayId) { | 
|  | mType = type; | 
|  | mDeviceId = deviceId; | 
|  | mEventTimeNanos = eventTimeNanos; | 
|  | mSource = source; | 
|  | mDisplayId = displayId; | 
|  | } | 
|  | /** @hide */ | 
|  | protected VerifiedInputEvent(@NonNull Parcel in, int expectedType) { | 
|  | mType = in.readInt(); | 
|  | if (mType != expectedType) { | 
|  | throw new IllegalArgumentException("Unexpected input event type token in parcel."); | 
|  | } | 
|  | mDeviceId = in.readInt(); | 
|  | mEventTimeNanos = in.readLong(); | 
|  | mSource = in.readInt(); | 
|  | mDisplayId = in.readInt(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Get the id of the device that generated this event. | 
|  | * | 
|  | * @see InputEvent#getDeviceId() | 
|  | */ | 
|  | public int getDeviceId() { | 
|  | return mDeviceId; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Get the time this event occurred, in the {@link android.os.SystemClock#uptimeMillis()} | 
|  | * time base. | 
|  | * | 
|  | * @see InputEvent#getEventTime() | 
|  | */ | 
|  | @SuppressLint("MethodNameUnits") | 
|  | public long getEventTimeNanos() { | 
|  | return mEventTimeNanos; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Get the source of the event. | 
|  | * | 
|  | * @see InputEvent#getSource() | 
|  | */ | 
|  | public int getSource() { | 
|  | return mSource; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Get the display id that is associated with this event. | 
|  | * | 
|  | * @see Display#getDisplayId() | 
|  | */ | 
|  | public int getDisplayId() { | 
|  | return mDisplayId; | 
|  | } | 
|  |  | 
|  | /** {@inheritDoc} */ | 
|  | @Override | 
|  | public void writeToParcel(@NonNull Parcel dest, int flags) { | 
|  | dest.writeInt(mType); | 
|  | dest.writeInt(mDeviceId); | 
|  | dest.writeLong(mEventTimeNanos); | 
|  | dest.writeInt(mSource); | 
|  | dest.writeInt(mDisplayId); | 
|  | } | 
|  |  | 
|  | /** {@inheritDoc} */ | 
|  | @Override | 
|  | public int describeContents() { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | private static int peekInt(@NonNull Parcel parcel) { | 
|  | final int initialDataPosition = parcel.dataPosition(); | 
|  | int data = parcel.readInt(); | 
|  | parcel.setDataPosition(initialDataPosition); | 
|  | return data; | 
|  | } | 
|  |  | 
|  | public static final @NonNull Parcelable.Creator<VerifiedInputEvent> CREATOR = | 
|  | new Parcelable.Creator<VerifiedInputEvent>() { | 
|  | @Override | 
|  | public VerifiedInputEvent[] newArray(int size) { | 
|  | return new VerifiedInputEvent[size]; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public VerifiedInputEvent createFromParcel(@NonNull Parcel in) { | 
|  | final int type = peekInt(in); | 
|  | if (type == VERIFIED_KEY) { | 
|  | return VerifiedKeyEvent.CREATOR.createFromParcel(in); | 
|  | } else if (type == VERIFIED_MOTION) { | 
|  | return VerifiedMotionEvent.CREATOR.createFromParcel(in); | 
|  | } | 
|  | throw new IllegalArgumentException("Unexpected input event type in parcel."); | 
|  | } | 
|  | }; | 
|  |  | 
|  | @Override | 
|  | public boolean equals(@Nullable Object o) { | 
|  | if (this == o) return true; | 
|  | if (o == null || getClass() != o.getClass()) return false; | 
|  | @SuppressWarnings("unchecked") | 
|  | VerifiedInputEvent that = (VerifiedInputEvent) o; | 
|  | return mType == that.mType | 
|  | && getDeviceId() == that.getDeviceId() | 
|  | && getEventTimeNanos() == that.getEventTimeNanos() | 
|  | && getSource() == that.getSource() | 
|  | && getDisplayId() == that.getDisplayId(); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public int hashCode() { | 
|  | int _hash = 1; | 
|  | _hash = 31 * _hash + mType; | 
|  | _hash = 31 * _hash + getDeviceId(); | 
|  | _hash = 31 * _hash + Long.hashCode(getEventTimeNanos()); | 
|  | _hash = 31 * _hash + getSource(); | 
|  | _hash = 31 * _hash + getDisplayId(); | 
|  | return _hash; | 
|  | } | 
|  | } |