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

#define LOG_TAG "InputQueue-JNI"

//#define LOG_NDEBUG 0

// Log debug messages about the dispatch cycle.
#define DEBUG_DISPATCH_CYCLE 0

// Log debug messages about registrations.
#define DEBUG_REGISTRATION 0


#include "JNIHelp.h"

#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
#include <utils/PollLoop.h>
#include <utils/KeyedVector.h>
#include <utils/threads.h>
#include <ui/InputTransport.h>
#include "android_os_MessageQueue.h"
#include "android_view_InputChannel.h"
#include "android_view_KeyEvent.h"
#include "android_view_MotionEvent.h"

namespace android {

// ----------------------------------------------------------------------------

static struct {
    jclass clazz;

    jmethodID dispatchKeyEvent;
    jmethodID dispatchMotionEvent;
} gInputQueueClassInfo;

// ----------------------------------------------------------------------------

class NativeInputQueue {
public:
    NativeInputQueue();
    ~NativeInputQueue();

    status_t registerInputChannel(JNIEnv* env, jobject inputChannelObj,
            jobject inputHandlerObj, jobject messageQueueObj);

    status_t unregisterInputChannel(JNIEnv* env, jobject inputChannelObj);

    status_t finished(JNIEnv* env, jlong finishedToken, bool ignoreSpuriousFinish);

private:
    class Connection : public RefBase {
    protected:
        virtual ~Connection();

    public:
        enum Status {
            // Everything is peachy.
            STATUS_NORMAL,
            // The input channel has been unregistered.
            STATUS_ZOMBIE
        };

        Connection(uint16_t id,
                const sp<InputChannel>& inputChannel, const sp<PollLoop>& pollLoop);

        inline const char* getInputChannelName() const { return inputChannel->getName().string(); }

        // A unique id for this connection.
        uint16_t id;

        Status status;

        sp<InputChannel> inputChannel;
        InputConsumer inputConsumer;
        sp<PollLoop> pollLoop;
        jobject inputHandlerObjGlobal;
        PreallocatedInputEventFactory inputEventFactory;

        // The sequence number of the current event being dispatched.
        // This is used as part of the finished token as a way to determine whether the finished
        // token is still valid before sending a finished signal back to the publisher.
        uint16_t messageSeqNum;

        // True if a message has been received from the publisher but not yet finished.
        bool messageInProgress;
    };

    Mutex mLock;
    uint16_t mNextConnectionId;
    KeyedVector<int32_t, sp<Connection> > mConnectionsByReceiveFd;

    ssize_t getConnectionIndex(const sp<InputChannel>& inputChannel);

    static void handleInputChannelDisposed(JNIEnv* env,
            jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data);

    static bool handleReceiveCallback(int receiveFd, int events, void* data);

    static jlong generateFinishedToken(int32_t receiveFd,
            uint16_t connectionId, uint16_t messageSeqNum);

    static void parseFinishedToken(jlong finishedToken,
            int32_t* outReceiveFd, uint16_t* outConnectionId, uint16_t* outMessageIndex);
};

// ----------------------------------------------------------------------------

NativeInputQueue::NativeInputQueue() :
        mNextConnectionId(0) {
}

NativeInputQueue::~NativeInputQueue() {
}

status_t NativeInputQueue::registerInputChannel(JNIEnv* env, jobject inputChannelObj,
        jobject inputHandlerObj, jobject messageQueueObj) {
    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
            inputChannelObj);
    if (inputChannel == NULL) {
        LOGW("Input channel is not initialized.");
        return BAD_VALUE;
    }

#if DEBUG_REGISTRATION
    LOGD("channel '%s' - Registered", inputChannel->getName().string());
#endif

    sp<PollLoop> pollLoop = android_os_MessageQueue_getPollLoop(env, messageQueueObj);

    { // acquire lock
        AutoMutex _l(mLock);

        if (getConnectionIndex(inputChannel) >= 0) {
            LOGW("Attempted to register already registered input channel '%s'",
                    inputChannel->getName().string());
            return BAD_VALUE;
        }

        uint16_t connectionId = mNextConnectionId++;
        sp<Connection> connection = new Connection(connectionId, inputChannel, pollLoop);
        status_t result = connection->inputConsumer.initialize();
        if (result) {
            LOGW("Failed to initialize input consumer for input channel '%s', status=%d",
                    inputChannel->getName().string(), result);
            return result;
        }

        connection->inputHandlerObjGlobal = env->NewGlobalRef(inputHandlerObj);

        int32_t receiveFd = inputChannel->getReceivePipeFd();
        mConnectionsByReceiveFd.add(receiveFd, connection);

        pollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this);
    } // release lock

    android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
            handleInputChannelDisposed, this);
    return OK;
}

status_t NativeInputQueue::unregisterInputChannel(JNIEnv* env, jobject inputChannelObj) {
    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
            inputChannelObj);
    if (inputChannel == NULL) {
        LOGW("Input channel is not initialized.");
        return BAD_VALUE;
    }

#if DEBUG_REGISTRATION
    LOGD("channel '%s' - Unregistered", inputChannel->getName().string());
#endif

    { // acquire lock
        AutoMutex _l(mLock);

        ssize_t connectionIndex = getConnectionIndex(inputChannel);
        if (connectionIndex < 0) {
            LOGW("Attempted to unregister already unregistered input channel '%s'",
                    inputChannel->getName().string());
            return BAD_VALUE;
        }

        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
        mConnectionsByReceiveFd.removeItemsAt(connectionIndex);

        connection->status = Connection::STATUS_ZOMBIE;

        connection->pollLoop->removeCallback(inputChannel->getReceivePipeFd());

        env->DeleteGlobalRef(connection->inputHandlerObjGlobal);
        connection->inputHandlerObjGlobal = NULL;

        if (connection->messageInProgress) {
            LOGI("Sending finished signal for input channel '%s' since it is being unregistered "
                    "while an input message is still in progress.",
                    connection->getInputChannelName());
            connection->messageInProgress = false;
            connection->inputConsumer.sendFinishedSignal(); // ignoring result
        }
    } // release lock

    android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
    return OK;
}

ssize_t NativeInputQueue::getConnectionIndex(const sp<InputChannel>& inputChannel) {
    ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
    if (connectionIndex >= 0) {
        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
        if (connection->inputChannel.get() == inputChannel.get()) {
            return connectionIndex;
        }
    }

    return -1;
}

status_t NativeInputQueue::finished(JNIEnv* env, jlong finishedToken, bool ignoreSpuriousFinish) {
    int32_t receiveFd;
    uint16_t connectionId;
    uint16_t messageSeqNum;
    parseFinishedToken(finishedToken, &receiveFd, &connectionId, &messageSeqNum);

    { // acquire lock
        AutoMutex _l(mLock);

        ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);
        if (connectionIndex < 0) {
            if (! ignoreSpuriousFinish) {
                LOGI("Ignoring finish signal on channel that is no longer registered.");
            }
            return DEAD_OBJECT;
        }

        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
        if (connectionId != connection->id) {
            if (! ignoreSpuriousFinish) {
                LOGI("Ignoring finish signal on channel that is no longer registered.");
            }
            return DEAD_OBJECT;
        }

        if (messageSeqNum != connection->messageSeqNum || ! connection->messageInProgress) {
            if (! ignoreSpuriousFinish) {
                LOGW("Attempted to finish input twice on channel '%s'.  "
                        "finished messageSeqNum=%d, current messageSeqNum=%d, messageInProgress=%d",
                        connection->getInputChannelName(),
                        messageSeqNum, connection->messageSeqNum, connection->messageInProgress);
            }
            return INVALID_OPERATION;
        }

        connection->messageInProgress = false;

        status_t status = connection->inputConsumer.sendFinishedSignal();
        if (status) {
            LOGW("Failed to send finished signal on channel '%s'.  status=%d",
                    connection->getInputChannelName(), status);
            return status;
        }

#if DEBUG_DISPATCH_CYCLE
        LOGD("channel '%s' ~ Finished event.",
                connection->getInputChannelName());
#endif
    } // release lock

    return OK;
}

void NativeInputQueue::handleInputChannelDisposed(JNIEnv* env,
        jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
    LOGW("Input channel object '%s' was disposed without first being unregistered with "
            "the input queue!", inputChannel->getName().string());

    NativeInputQueue* q = static_cast<NativeInputQueue*>(data);
    q->unregisterInputChannel(env, inputChannelObj);
}

bool NativeInputQueue::handleReceiveCallback(int receiveFd, int events, void* data) {
    NativeInputQueue* q = static_cast<NativeInputQueue*>(data);
    JNIEnv* env = AndroidRuntime::getJNIEnv();

    sp<Connection> connection;
    InputEvent* inputEvent;
    jobject inputHandlerObjLocal;
    jlong finishedToken;
    { // acquire lock
        AutoMutex _l(q->mLock);

        ssize_t connectionIndex = q->mConnectionsByReceiveFd.indexOfKey(receiveFd);
        if (connectionIndex < 0) {
            LOGE("Received spurious receive callback for unknown input channel.  "
                    "fd=%d, events=0x%x", receiveFd, events);
            return false; // remove the callback
        }

        connection = q->mConnectionsByReceiveFd.valueAt(connectionIndex);
        if (events & (POLLERR | POLLHUP | POLLNVAL)) {
            LOGE("channel '%s' ~ Publisher closed input channel or an error occurred.  "
                    "events=0x%x", connection->getInputChannelName(), events);
            return false; // remove the callback
        }

        if (! (events & POLLIN)) {
            LOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
                    "events=0x%x", connection->getInputChannelName(), events);
            return true;
        }

        status_t status = connection->inputConsumer.receiveDispatchSignal();
        if (status) {
            LOGE("channel '%s' ~ Failed to receive dispatch signal.  status=%d",
                    connection->getInputChannelName(), status);
            return false; // remove the callback
        }

        if (connection->messageInProgress) {
            LOGW("channel '%s' ~ Publisher sent spurious dispatch signal.",
                    connection->getInputChannelName());
            return true;
        }

        status = connection->inputConsumer.consume(& connection->inputEventFactory, & inputEvent);
        if (status) {
            LOGW("channel '%s' ~ Failed to consume input event.  status=%d",
                    connection->getInputChannelName(), status);
            connection->inputConsumer.sendFinishedSignal();
            return true;
        }

        connection->messageInProgress = true;
        connection->messageSeqNum += 1;

        finishedToken = generateFinishedToken(receiveFd, connection->id, connection->messageSeqNum);

        inputHandlerObjLocal = env->NewLocalRef(connection->inputHandlerObjGlobal);
    } // release lock

    // Invoke the handler outside of the lock.
    //
    // Note: inputEvent is stored in a field of the connection object which could potentially
    //       become disposed due to the input channel being unregistered concurrently.
    //       For this reason, we explicitly keep the connection object alive by holding
    //       a strong pointer to it within this scope.  We also grabbed a local reference to
    //       the input handler object itself for the same reason.

    int32_t inputEventType = inputEvent->getType();

    jobject inputEventObj;
    jmethodID dispatchMethodId;
    switch (inputEventType) {
    case AINPUT_EVENT_TYPE_KEY:
#if DEBUG_DISPATCH_CYCLE
        LOGD("channel '%s' ~ Received key event.", connection->getInputChannelName());
#endif
        inputEventObj = android_view_KeyEvent_fromNative(env,
                static_cast<KeyEvent*>(inputEvent));
        dispatchMethodId = gInputQueueClassInfo.dispatchKeyEvent;
        break;

    case AINPUT_EVENT_TYPE_MOTION:
#if DEBUG_DISPATCH_CYCLE
        LOGD("channel '%s' ~ Received motion event.", connection->getInputChannelName());
#endif
        inputEventObj = android_view_MotionEvent_fromNative(env,
                static_cast<MotionEvent*>(inputEvent));
        dispatchMethodId = gInputQueueClassInfo.dispatchMotionEvent;
        break;

    default:
        assert(false); // InputConsumer should prevent this from ever happening
        inputEventObj = NULL;
    }

    if (! inputEventObj) {
        LOGW("channel '%s' ~ Failed to obtain DVM event object.",
                connection->getInputChannelName());
        env->DeleteLocalRef(inputHandlerObjLocal);
        q->finished(env, finishedToken, false);
        return true;
    }

#if DEBUG_DISPATCH_CYCLE
    LOGD("Invoking input handler.");
#endif
    env->CallStaticVoidMethod(gInputQueueClassInfo.clazz,
            dispatchMethodId, inputHandlerObjLocal, inputEventObj,
            jlong(finishedToken));
#if DEBUG_DISPATCH_CYCLE
    LOGD("Returned from input handler.");
#endif

    if (env->ExceptionCheck()) {
        LOGE("An exception occurred while invoking the input handler for an event.");
        LOGE_EX(env);
        env->ExceptionClear();

        q->finished(env, finishedToken, true /*ignoreSpuriousFinish*/);
    }

    env->DeleteLocalRef(inputEventObj);
    env->DeleteLocalRef(inputHandlerObjLocal);
    return true;
}

jlong NativeInputQueue::generateFinishedToken(int32_t receiveFd, uint16_t connectionId,
        uint16_t messageSeqNum) {
    return (jlong(receiveFd) << 32) | (jlong(connectionId) << 16) | jlong(messageSeqNum);
}

void NativeInputQueue::parseFinishedToken(jlong finishedToken,
        int32_t* outReceiveFd, uint16_t* outConnectionId, uint16_t* outMessageIndex) {
    *outReceiveFd = int32_t(finishedToken >> 32);
    *outConnectionId = uint16_t(finishedToken >> 16);
    *outMessageIndex = uint16_t(finishedToken);
}

// ----------------------------------------------------------------------------

NativeInputQueue::Connection::Connection(uint16_t id,
        const sp<InputChannel>& inputChannel, const sp<PollLoop>& pollLoop) :
    id(id), status(STATUS_NORMAL), inputChannel(inputChannel), inputConsumer(inputChannel),
    pollLoop(pollLoop), inputHandlerObjGlobal(NULL),
    messageSeqNum(0), messageInProgress(false) {
}

NativeInputQueue::Connection::~Connection() {
}

// ----------------------------------------------------------------------------

static NativeInputQueue gNativeInputQueue;

static void android_view_InputQueue_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
        jobject inputChannelObj, jobject inputHandlerObj, jobject messageQueueObj) {
    status_t status = gNativeInputQueue.registerInputChannel(
            env, inputChannelObj, inputHandlerObj, messageQueueObj);

    if (status) {
        jniThrowRuntimeException(env, "Failed to register input channel.  "
                "Check logs for details.");
    }
}

static void android_view_InputQueue_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
        jobject inputChannelObj) {
    status_t status = gNativeInputQueue.unregisterInputChannel(env, inputChannelObj);

    if (status) {
        jniThrowRuntimeException(env, "Failed to unregister input channel.  "
                "Check logs for details.");
    }
}

static void android_view_InputQueue_nativeFinished(JNIEnv* env, jclass clazz,
        jlong finishedToken) {
    status_t status = gNativeInputQueue.finished(
            env, finishedToken, false /*ignoreSpuriousFinish*/);

    // We ignore the case where an event could not be finished because the input channel
    // was no longer registered (DEAD_OBJECT) since it is a common race that can occur
    // during application shutdown.  The input dispatcher recovers gracefully anyways.
    if (status != OK && status != DEAD_OBJECT) {
        jniThrowRuntimeException(env, "Failed to finish input event.  "
                "Check logs for details.");
    }
}

// ----------------------------------------------------------------------------

static JNINativeMethod gInputQueueMethods[] = {
    /* name, signature, funcPtr */
    { "nativeRegisterInputChannel",
            "(Landroid/view/InputChannel;Landroid/view/InputHandler;Landroid/os/MessageQueue;)V",
            (void*)android_view_InputQueue_nativeRegisterInputChannel },
    { "nativeUnregisterInputChannel",
            "(Landroid/view/InputChannel;)V",
            (void*)android_view_InputQueue_nativeUnregisterInputChannel },
    { "nativeFinished", "(J)V",
            (void*)android_view_InputQueue_nativeFinished }
};

#define FIND_CLASS(var, className) \
        var = env->FindClass(className); \
        LOG_FATAL_IF(! var, "Unable to find class " className); \
        var = jclass(env->NewGlobalRef(var));

#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
        var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
        LOG_FATAL_IF(! var, "Unable to find static method " methodName);

int register_android_view_InputQueue(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "android/view/InputQueue",
            gInputQueueMethods, NELEM(gInputQueueMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    FIND_CLASS(gInputQueueClassInfo.clazz, "android/view/InputQueue");

    GET_STATIC_METHOD_ID(gInputQueueClassInfo.dispatchKeyEvent, gInputQueueClassInfo.clazz,
            "dispatchKeyEvent",
            "(Landroid/view/InputHandler;Landroid/view/KeyEvent;J)V");

    GET_STATIC_METHOD_ID(gInputQueueClassInfo.dispatchMotionEvent, gInputQueueClassInfo.clazz,
            "dispatchMotionEvent",
            "(Landroid/view/InputHandler;Landroid/view/MotionEvent;J)V");
    return 0;
}

} // namespace android
