/*
 * Copyright (C) 2019 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.
 */

#ifndef _UI_INPUT_INPUTDISPATCHER_ENTRY_H
#define _UI_INPUT_INPUTDISPATCHER_ENTRY_H

#include "InjectionState.h"
#include "InputTarget.h"

#include <input/Input.h>
#include <input/InputApplication.h>
#include <stdint.h>
#include <utils/Timers.h>
#include <functional>
#include <string>

namespace android::inputdispatcher {

struct EventEntry {
    enum class Type {
        CONFIGURATION_CHANGED,
        DEVICE_RESET,
        FOCUS,
        KEY,
        MOTION,
        SENSOR,
        POINTER_CAPTURE_CHANGED,
        DRAG,
    };

    int32_t id;
    Type type;
    nsecs_t eventTime;
    uint32_t policyFlags;
    InjectionState* injectionState;

    bool dispatchInProgress; // initially false, set to true while dispatching

    /**
     * Injected keys are events from an external (probably untrusted) application
     * and are not related to real hardware state. They come in via
     * InputDispatcher::injectInputEvent, which sets policy flag POLICY_FLAG_INJECTED.
     */
    inline bool isInjected() const { return injectionState != nullptr; }

    /**
     * Synthesized events are either injected events, or events that come
     * from real hardware, but aren't directly attributable to a specific hardware event.
     * Key repeat is a synthesized event, because it is related to an actual hardware state
     * (a key is currently pressed), but the repeat itself is generated by the framework.
     */
    inline bool isSynthesized() const {
        return isInjected() || IdGenerator::getSource(id) != IdGenerator::Source::INPUT_READER;
    }

    virtual std::string getDescription() const = 0;

    EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags);
    virtual ~EventEntry();

protected:
    void releaseInjectionState();
};

struct ConfigurationChangedEntry : EventEntry {
    explicit ConfigurationChangedEntry(int32_t id, nsecs_t eventTime);
    std::string getDescription() const override;

    ~ConfigurationChangedEntry() override;
};

struct DeviceResetEntry : EventEntry {
    int32_t deviceId;

    DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId);
    std::string getDescription() const override;

    ~DeviceResetEntry() override;
};

struct FocusEntry : EventEntry {
    sp<IBinder> connectionToken;
    bool hasFocus;
    std::string reason;

    FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus,
               const std::string& reason);
    std::string getDescription() const override;

    ~FocusEntry() override;
};

struct PointerCaptureChangedEntry : EventEntry {
    bool pointerCaptureEnabled;

    PointerCaptureChangedEntry(int32_t id, nsecs_t eventTime, bool hasPointerCapture);
    std::string getDescription() const override;

    ~PointerCaptureChangedEntry() override;
};

struct DragEntry : EventEntry {
    sp<IBinder> connectionToken;
    bool isExiting;
    float x, y;

    DragEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool isExiting, float x,
              float y);
    std::string getDescription() const override;

    ~DragEntry() override;
};

struct KeyEntry : EventEntry {
    int32_t deviceId;
    uint32_t source;
    int32_t displayId;
    int32_t action;
    int32_t flags;
    int32_t keyCode;
    int32_t scanCode;
    int32_t metaState;
    int32_t repeatCount;
    nsecs_t downTime;

    bool syntheticRepeat; // set to true for synthetic key repeats

    enum InterceptKeyResult {
        INTERCEPT_KEY_RESULT_UNKNOWN,
        INTERCEPT_KEY_RESULT_SKIP,
        INTERCEPT_KEY_RESULT_CONTINUE,
        INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
    };
    InterceptKeyResult interceptKeyResult; // set based on the interception result
    nsecs_t interceptKeyWakeupTime;        // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER

    KeyEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
             uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
             int32_t metaState, int32_t repeatCount, nsecs_t downTime);
    std::string getDescription() const override;
    void recycle();

    ~KeyEntry() override;
};

struct MotionEntry : EventEntry {
    int32_t deviceId;
    uint32_t source;
    int32_t displayId;
    int32_t action;
    int32_t actionButton;
    int32_t flags;
    int32_t metaState;
    int32_t buttonState;
    MotionClassification classification;
    int32_t edgeFlags;
    float xPrecision;
    float yPrecision;
    float xCursorPosition;
    float yCursorPosition;
    nsecs_t downTime;
    uint32_t pointerCount;
    PointerProperties pointerProperties[MAX_POINTERS];
    PointerCoords pointerCoords[MAX_POINTERS];

    MotionEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
                uint32_t policyFlags, int32_t action, int32_t actionButton, int32_t flags,
                int32_t metaState, int32_t buttonState, MotionClassification classification,
                int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
                float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
                float xOffset, float yOffset);
    std::string getDescription() const override;

    virtual ~MotionEntry();
};

struct SensorEntry : EventEntry {
    int32_t deviceId;
    uint32_t source;
    InputDeviceSensorType sensorType;
    InputDeviceSensorAccuracy accuracy;
    bool accuracyChanged;
    nsecs_t hwTimestamp;

    std::vector<float> values;

    SensorEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source,
                uint32_t policyFlags, nsecs_t hwTimestamp, InputDeviceSensorType sensorType,
                InputDeviceSensorAccuracy accuracy, bool accuracyChanged,
                std::vector<float> values);
    std::string getDescription() const override;

    ~SensorEntry() override;
};

// Tracks the progress of dispatching a particular event to a particular connection.
struct DispatchEntry {
    const uint32_t seq; // unique sequence number, never 0

    std::shared_ptr<EventEntry> eventEntry; // the event to dispatch
    int32_t targetFlags;
    ui::Transform transform;
    float globalScaleFactor;
    int2 displaySize;
    // Both deliveryTime and timeoutTime are only populated when the entry is sent to the app,
    // and will be undefined before that.
    nsecs_t deliveryTime; // time when the event was actually delivered
    // An ANR will be triggered if a response for this entry is not received by timeoutTime
    nsecs_t timeoutTime;

    // Set to the resolved ID, action and flags when the event is enqueued.
    int32_t resolvedEventId;
    int32_t resolvedAction;
    int32_t resolvedFlags;

    DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags,
                  ui::Transform transform, float globalScaleFactor, int2 displaySize);

    inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; }

    inline bool isSplit() const { return targetFlags & InputTarget::FLAG_SPLIT; }

private:
    static volatile int32_t sNextSeqAtomic;

    static uint32_t nextSeq();
};

VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry);
VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry);

class InputDispatcher;
// A command entry captures state and behavior for an action to be performed in the
// dispatch loop after the initial processing has taken place.  It is essentially
// a kind of continuation used to postpone sensitive policy interactions to a point
// in the dispatch loop where it is safe to release the lock (generally after finishing
// the critical parts of the dispatch cycle).
//
// The special thing about commands is that they can voluntarily release and reacquire
// the dispatcher lock at will.  Initially when the command starts running, the
// dispatcher lock is held.  However, if the command needs to call into the policy to
// do some work, it can release the lock, do the work, then reacquire the lock again
// before returning.
//
// This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
// never calls into the policy while holding its lock.
//
// Commands are implicitly 'LockedInterruptible'.
struct CommandEntry;
typedef std::function<void(InputDispatcher&, CommandEntry*)> Command;

class Connection;
struct CommandEntry {
    explicit CommandEntry(Command command);
    ~CommandEntry();

    Command command;

    // parameters for the command (usage varies by command)
    sp<Connection> connection;
    nsecs_t eventTime;
    std::shared_ptr<KeyEntry> keyEntry;
    std::shared_ptr<SensorEntry> sensorEntry;
    std::shared_ptr<InputApplicationHandle> inputApplicationHandle;
    std::string reason;
    int32_t userActivityEventType;
    uint32_t seq;
    bool handled;
    sp<IBinder> connectionToken;
    sp<IBinder> oldToken;
    sp<IBinder> newToken;
    std::string obscuringPackage;
    bool enabled;
    int32_t pid;
    nsecs_t consumeTime; // time when the event was consumed by InputConsumer
    int32_t displayId;
    float x;
    float y;
};

} // namespace android::inputdispatcher

#endif // _UI_INPUT_INPUTDISPATCHER_ENTRY_H
