/*
 * 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 android.view.KeyEvent.FLAG_CANCELED;
import static android.view.KeyEvent.FLAG_IS_ACCESSIBILITY_EVENT;

import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.DataClass;

import java.lang.annotation.Retention;

/**
 * KeyEvent that has been verified by the system.
 * The data contained in this class is always a subset of a {@link KeyEvent}. Use this class to
 * check which data has been confirmed by the system to be authentic.
 *
 * Most applications do not need to use this class.
 *
 * {@see android.hardware.input.InputManager#verifyInputEvent}
 */
@DataClass(genHiddenConstructor = true, genEqualsHashCode = true)
public final class VerifiedKeyEvent extends VerifiedInputEvent implements Parcelable {
    private static final String TAG = "VerifiedKeyEvent";

    /** @hide */
    @Retention(SOURCE)
    @IntDef({KeyEvent.ACTION_DOWN, KeyEvent.ACTION_UP})
    public @interface KeyEventAction {};

    /**
     * The action of this key event.  May be either {@link KeyEvent#ACTION_DOWN} or
     * {@link KeyEvent#ACTION_UP}.
     *
     * @see KeyEvent#getAction()
     */
    @KeyEventAction
    private int mAction;

    /**
     * Retrieve the time of the most recent key down event, in the
     * {@link android.os.SystemClock#uptimeMillis} time base, but in nanoseconds. If this
     * is a down event, this will be the same as {@link VerifiedInputEvent#getEventTimeNanos()}.
     *
     * @see KeyEvent#getDownTime()
     */
    @SuppressLint({"MethodNameUnits"})
    private long mDownTimeNanos;

    /**
     * Returns the flags for this key event.
     *
     * @see KeyEvent#getFlags()
     * @see KeyEvent#FLAG_CANCELED
     * @see KeyEvent#FLAG_IS_ACCESSIBILITY_EVENT
     *
     * @hide
     */
    private int mFlags;

    /**
     * Retrieve the key code of the key event.
     *
     * @see KeyEvent#getKeyCode()
     */
    private int mKeyCode;

    /**
     * Retrieve the hardware key id of this key event. These values are not reliable
     * and vary from device to device.
     *
     * @see KeyEvent#getScanCode()
     */
    private int mScanCode;

    /**
     * <p>Returns the state of the meta keys.</p>
     *
     * @return an integer in which each bit set to 1 represents a pressed meta key
     * @see KeyEvent#getMetaState()
     */
    private int mMetaState;

    /**
     * Retrieve the repeat count of the event.  For key down events, this is the number of times
     * the key has repeated with the first down starting at 0 and counting up from there.
     * For key up events, this is always equal to zero. For multiple key events,
     * this is the number of down/up pairs that have occurred.
     */
    private int mRepeatCount;

    /**
     * Get a specific flag of this key event, if possible. Return null if the flag value could
     * not be checked.
     *
     * @param flag the flag of interest
     * @return Boolean(true) if the key event has the requested flag
     *         Boolean(false) if the key event does not have the requested flag
     *         null if the flag value could not be checked
     *
     * @see KeyEvent#getFlags()
     * @see KeyEvent#FLAG_CANCELED
     */
    public @Nullable Boolean getFlag(int flag) {
        switch(flag) {
            // InputDispatcher only verifies a subset of the KeyEvent flags.
            // These values must be kept in sync with Input.cpp
            case FLAG_CANCELED:
            case FLAG_IS_ACCESSIBILITY_EVENT:
                return (mFlags & flag) != 0;
        }
        return null;
    }

    // The codegen tool doesn't fully support subclasses, since it works on a per-file basis.
    // To modify this file:
    // 1. run codegen on this file
    // 2. edit the constructor signature
    // 3. add the "super" call for constructor that receives a Parcel
    // 4. add the "super" call to the writeToParcel method
    // 5. Update "equals" and "hashcode" methods to include VerifiedInputEvent fields



    // Code below generated by codegen v1.0.20.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
    //
    // To regenerate run:
    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/VerifiedKeyEvent.java
    //
    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
    //   Settings > Editor > Code Style > Formatter Control
    //@formatter:off


    /**
     * Creates a new VerifiedKeyEvent.
     *
     * @param action
     *   The action of this key event.  May be either {@link KeyEvent#ACTION_DOWN} or
     *   {@link KeyEvent#ACTION_UP}.
     * @param downTimeNanos
     *   Retrieve the time of the most recent key down event, in the
     *   {@link android.os.SystemClock#uptimeMillis} time base, but in nanoseconds. If this
     *   is a down event, this will be the same as {@link VerifiedInputEvent#getEventTimeNanos()}.
     * @param flags
     *   Returns the flags for this key event.
     * @param keyCode
     *   Retrieve the key code of the key event.
     * @param scanCode
     *   Retrieve the hardware key id of this key event. These values are not reliable
     *   and vary from device to device.
     * @param metaState
     *   <p>Returns the state of the meta keys.</p>
     * @param repeatCount
     *   Retrieve the repeat count of the event.  For key down events, this is the number of times
     *   the key has repeated with the first down starting at 0 and counting up from there.
     *   For key up events, this is always equal to zero. For multiple key events,
     *   this is the number of down/up pairs that have occurred.
     * @hide
     */
    public VerifiedKeyEvent(
            int deviceId,
            long eventTimeNanos,
            int source,
            int displayId,
            @KeyEventAction int action,
            @SuppressLint({ "MethodNameUnits" }) long downTimeNanos,
            int flags,
            int keyCode,
            int scanCode,
            int metaState,
            int repeatCount) {
        super(VERIFIED_KEY, deviceId, eventTimeNanos, source, displayId);
        this.mAction = action;
        com.android.internal.util.AnnotationValidations.validate(
                KeyEventAction.class, null, mAction);
        this.mDownTimeNanos = downTimeNanos;
        this.mFlags = flags;
        this.mKeyCode = keyCode;
        this.mScanCode = scanCode;
        this.mMetaState = metaState;
        this.mRepeatCount = repeatCount;
    }

    /**
     * The action of this key event.  May be either {@link KeyEvent#ACTION_DOWN} or
     * {@link KeyEvent#ACTION_UP}.
     *
     * @see KeyEvent#getAction()
     */
    @DataClass.Generated.Member
    public @KeyEventAction int getAction() {
        return mAction;
    }

    /**
     * Retrieve the time of the most recent key down event, in the
     * {@link android.os.SystemClock#uptimeMillis} time base, but in nanoseconds. If this
     * is a down event, this will be the same as {@link VerifiedInputEvent#getEventTimeNanos()}.
     *
     * @see KeyEvent#getDownTime()
     */
    @DataClass.Generated.Member
    public @SuppressLint({ "MethodNameUnits" }) long getDownTimeNanos() {
        return mDownTimeNanos;
    }

    /**
     * Returns the flags for this key event.
     *
     * @see KeyEvent#getFlags()
     * @see KeyEvent#FLAG_CANCELED
     * @hide
     */
    @DataClass.Generated.Member
    public int getFlags() {
        return mFlags;
    }

    /**
     * Retrieve the key code of the key event.
     *
     * @see KeyEvent#getKeyCode()
     */
    @DataClass.Generated.Member
    public int getKeyCode() {
        return mKeyCode;
    }

    /**
     * Retrieve the hardware key id of this key event. These values are not reliable
     * and vary from device to device.
     *
     * @see KeyEvent#getScanCode()
     */
    @DataClass.Generated.Member
    public int getScanCode() {
        return mScanCode;
    }

    /**
     * <p>Returns the state of the meta keys.</p>
     *
     * @return an integer in which each bit set to 1 represents a pressed meta key
     * @see KeyEvent#getMetaState()
     */
    @DataClass.Generated.Member
    public int getMetaState() {
        return mMetaState;
    }

    /**
     * Retrieve the repeat count of the event.  For key down events, this is the number of times
     * the key has repeated with the first down starting at 0 and counting up from there.
     * For key up events, this is always equal to zero. For multiple key events,
     * this is the number of down/up pairs that have occurred.
     */
    @DataClass.Generated.Member
    public int getRepeatCount() {
        return mRepeatCount;
    }

    @Override
    @DataClass.Generated.Member
    public boolean equals(@Nullable Object o) {
        // You can override field equality logic by defining either of the methods like:
        // boolean fieldNameEquals(VerifiedKeyEvent other) { ... }
        // boolean fieldNameEquals(FieldType otherValue) { ... }

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        @SuppressWarnings("unchecked")
        VerifiedKeyEvent that = (VerifiedKeyEvent) o;
        //noinspection PointlessBooleanExpression
        return true
                && super.equals(that)
                && mAction == that.mAction
                && mDownTimeNanos == that.mDownTimeNanos
                && mFlags == that.mFlags
                && mKeyCode == that.mKeyCode
                && mScanCode == that.mScanCode
                && mMetaState == that.mMetaState
                && mRepeatCount == that.mRepeatCount;
    }

    @Override
    @DataClass.Generated.Member
    public int hashCode() {
        // You can override field hashCode logic by defining methods like:
        // int fieldNameHashCode() { ... }

        int _hash = 1;
        _hash = 31 * _hash + super.hashCode();
        _hash = 31 * _hash + mAction;
        _hash = 31 * _hash + Long.hashCode(mDownTimeNanos);
        _hash = 31 * _hash + mFlags;
        _hash = 31 * _hash + mKeyCode;
        _hash = 31 * _hash + mScanCode;
        _hash = 31 * _hash + mMetaState;
        _hash = 31 * _hash + mRepeatCount;
        return _hash;
    }

    @Override
    @DataClass.Generated.Member
    public void writeToParcel(@android.annotation.NonNull Parcel dest, int flags) {
        // You can override field parcelling by defining methods like:
        // void parcelFieldName(Parcel dest, int flags) { ... }
        super.writeToParcel(dest, flags);

        dest.writeInt(mAction);
        dest.writeLong(mDownTimeNanos);
        dest.writeInt(mFlags);
        dest.writeInt(mKeyCode);
        dest.writeInt(mScanCode);
        dest.writeInt(mMetaState);
        dest.writeInt(mRepeatCount);
    }

    @Override
    @DataClass.Generated.Member
    public int describeContents() { return 0; }

    /** @hide */
    @SuppressWarnings({"unchecked", "RedundantCast"})
    @DataClass.Generated.Member
    /* package-private */ VerifiedKeyEvent(@android.annotation.NonNull Parcel in) {
        // You can override field unparcelling by defining methods like:
        // static FieldType unparcelFieldName(Parcel in) { ... }
        super(in, VERIFIED_KEY);

        int action = in.readInt();
        long downTimeNanos = in.readLong();
        int flags = in.readInt();
        int keyCode = in.readInt();
        int scanCode = in.readInt();
        int metaState = in.readInt();
        int repeatCount = in.readInt();

        this.mAction = action;
        com.android.internal.util.AnnotationValidations.validate(
                KeyEventAction.class, null, mAction);
        this.mDownTimeNanos = downTimeNanos;
        this.mFlags = flags;
        this.mKeyCode = keyCode;
        this.mScanCode = scanCode;
        this.mMetaState = metaState;
        this.mRepeatCount = repeatCount;

        // onConstructed(); // You can define this method to get a callback
    }

    @DataClass.Generated.Member
    public static final @android.annotation.NonNull Parcelable.Creator<VerifiedKeyEvent> CREATOR
            = new Parcelable.Creator<VerifiedKeyEvent>() {
        @Override
        public VerifiedKeyEvent[] newArray(int size) {
            return new VerifiedKeyEvent[size];
        }

        @Override
        public VerifiedKeyEvent createFromParcel(@android.annotation.NonNull Parcel in) {
            return new VerifiedKeyEvent(in);
        }
    };

    @DataClass.Generated(
            time = 1604509197793L,
            codegenVersion = "1.0.20",
            sourceFile = "frameworks/base/core/java/android/view/VerifiedKeyEvent.java",
            inputSignatures = "private static final  java.lang.String TAG\nprivate @android.view.VerifiedKeyEvent.KeyEventAction int mAction\nprivate @android.annotation.SuppressLint long mDownTimeNanos\nprivate  int mFlags\nprivate  int mKeyCode\nprivate  int mScanCode\nprivate  int mMetaState\nprivate  int mRepeatCount\npublic @android.annotation.Nullable java.lang.Boolean getFlag(int)\nclass VerifiedKeyEvent extends android.view.VerifiedInputEvent implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true)")
    @Deprecated
    private void __metadata() {}


    //@formatter:on
    // End of generated code

}
