/*
 * 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 "NativeActivity"
#include <utils/Log.h>

#include <poll.h>
#include <dlfcn.h>
#include <fcntl.h>

#include <android_runtime/android_app_NativeActivity.h>
#include <android_runtime/android_util_AssetManager.h>
#include <android_runtime/android_view_Surface.h>
#include <android_runtime/AndroidRuntime.h>
#include <androidfw/InputTransport.h>

#include <gui/Surface.h>

#include <system/window.h>

#include <utils/Looper.h>

#include "JNIHelp.h"
#include "android_os_MessageQueue.h"
#include "android_view_InputChannel.h"
#include "android_view_KeyEvent.h"

#define LOG_TRACE(...)
//#define LOG_TRACE(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)

namespace android
{

static struct {
    jmethodID dispatchUnhandledKeyEvent;
    jmethodID preDispatchKeyEvent;
    jmethodID finish;
    jmethodID setWindowFlags;
    jmethodID setWindowFormat;
    jmethodID showIme;
    jmethodID hideIme;
} gNativeActivityClassInfo;

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

struct ActivityWork {
    int32_t cmd;
    int32_t arg1;
    int32_t arg2;
};

enum {
    CMD_DEF_KEY = 1,
    CMD_FINISH,
    CMD_SET_WINDOW_FORMAT,
    CMD_SET_WINDOW_FLAGS,
    CMD_SHOW_SOFT_INPUT,
    CMD_HIDE_SOFT_INPUT,
};

static void write_work(int fd, int32_t cmd, int32_t arg1=0, int32_t arg2=0) {
    ActivityWork work;
    work.cmd = cmd;
    work.arg1 = arg1;
    work.arg2 = arg2;
    
    LOG_TRACE("write_work: cmd=%d", cmd);

restart:
    int res = write(fd, &work, sizeof(work));
    if (res < 0 && errno == EINTR) {
        goto restart;
    }
    
    if (res == sizeof(work)) return;
    
    if (res < 0) ALOGW("Failed writing to work fd: %s", strerror(errno));
    else ALOGW("Truncated writing to work fd: %d", res);
}

static bool read_work(int fd, ActivityWork* outWork) {
    int res = read(fd, outWork, sizeof(ActivityWork));
    // no need to worry about EINTR, poll loop will just come back again.
    if (res == sizeof(ActivityWork)) return true;
    
    if (res < 0) ALOGW("Failed reading work fd: %s", strerror(errno));
    else ALOGW("Truncated reading work fd: %d", res);
    return false;
}

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

} // namespace android

using namespace android;

AInputQueue::AInputQueue(const sp<InputChannel>& channel, int workWrite) :
        mWorkWrite(workWrite), mConsumer(channel), mSeq(0) {
    int msgpipe[2];
    if (pipe(msgpipe)) {
        ALOGW("could not create pipe: %s", strerror(errno));
        mDispatchKeyRead = mDispatchKeyWrite = -1;
    } else {
        mDispatchKeyRead = msgpipe[0];
        mDispatchKeyWrite = msgpipe[1];
        int result = fcntl(mDispatchKeyRead, F_SETFL, O_NONBLOCK);
        SLOGW_IF(result != 0, "Could not make AInputQueue read pipe "
                "non-blocking: %s", strerror(errno));
        result = fcntl(mDispatchKeyWrite, F_SETFL, O_NONBLOCK);
        SLOGW_IF(result != 0, "Could not make AInputQueue write pipe "
                "non-blocking: %s", strerror(errno));
    }
}

AInputQueue::~AInputQueue() {
    close(mDispatchKeyRead);
    close(mDispatchKeyWrite);
}

void AInputQueue::attachLooper(ALooper* looper, int ident,
        ALooper_callbackFunc callback, void* data) {
    mLooper = static_cast<android::Looper*>(looper);
    mLooper->addFd(mConsumer.getChannel()->getFd(),
            ident, ALOOPER_EVENT_INPUT, callback, data);
    mLooper->addFd(mDispatchKeyRead,
            ident, ALOOPER_EVENT_INPUT, callback, data);
}

void AInputQueue::detachLooper() {
    mLooper->removeFd(mConsumer.getChannel()->getFd());
    mLooper->removeFd(mDispatchKeyRead);
}

int32_t AInputQueue::hasEvents() {
    struct pollfd pfd[2];

    pfd[0].fd = mConsumer.getChannel()->getFd();
    pfd[0].events = POLLIN;
    pfd[0].revents = 0;
    pfd[1].fd = mDispatchKeyRead;
    pfd[1].events = POLLIN;
    pfd[1].revents = 0;
    
    int nfd = poll(pfd, 2, 0);
    if (nfd <= 0) return 0;
    return ((pfd[0].revents & POLLIN) || (pfd[1].revents & POLLIN)) ? 1 : -1;
}

int32_t AInputQueue::getEvent(AInputEvent** outEvent) {
    *outEvent = NULL;

    char byteread;
    ssize_t nRead = read(mDispatchKeyRead, &byteread, 1);

    Mutex::Autolock _l(mLock);

    if (nRead == 1) {
        if (mDispatchingKeys.size() > 0) {
            KeyEvent* kevent = mDispatchingKeys[0];
            *outEvent = kevent;
            mDispatchingKeys.removeAt(0);
            in_flight_event inflight;
            inflight.event = kevent;
            inflight.seq = -1;
            inflight.finishSeq = 0;
            mInFlightEvents.push(inflight);
        }

        bool finishNow = false;
        if (mFinishPreDispatches.size() > 0) {
            finish_pre_dispatch finish(mFinishPreDispatches[0]);
            mFinishPreDispatches.removeAt(0);
            const size_t N = mInFlightEvents.size();
            for (size_t i=0; i<N; i++) {
                const in_flight_event& inflight(mInFlightEvents[i]);
                if (inflight.seq == finish.seq) {
                    *outEvent = inflight.event;
                    finishNow = finish.handled;
                }
            }
            if (*outEvent == NULL) {
                ALOGW("getEvent couldn't find inflight for seq %d", finish.seq);
            }
        }

        if (finishNow) {
            finishEvent(*outEvent, true, false);
            *outEvent = NULL;
            return -1;
        } else if (*outEvent != NULL) {
            return 0;
        }
    }

    uint32_t consumerSeq;
    InputEvent* myEvent = NULL;
    status_t res = mConsumer.consume(&mPooledInputEventFactory, true /*consumeBatches*/, -1,
            &consumerSeq, &myEvent);
    if (res != android::OK) {
        if (res != android::WOULD_BLOCK) {
            ALOGW("channel '%s' ~ Failed to consume input event.  status=%d",
                    mConsumer.getChannel()->getName().string(), res);
        }
        return -1;
    }

    if (mConsumer.hasDeferredEvent()) {
        wakeupDispatchLocked();
    }

    in_flight_event inflight;
    inflight.event = myEvent;
    inflight.seq = -1;
    inflight.finishSeq = consumerSeq;
    mInFlightEvents.push(inflight);

    *outEvent = myEvent;
    return 0;
}

bool AInputQueue::preDispatchEvent(AInputEvent* event) {
    if (((InputEvent*)event)->getType() != AINPUT_EVENT_TYPE_KEY) {
        // The IME only cares about key events.
        return false;
    }

    // For now we only send system keys to the IME...  this avoids having
    // critical keys like DPAD go through this path.  We really need to have
    // the IME report which keys it wants.
    if (!((KeyEvent*)event)->isSystemKey()) {
        return false;
    }

    return preDispatchKey((KeyEvent*)event);
}

void AInputQueue::finishEvent(AInputEvent* event, bool handled, bool didDefaultHandling) {
    LOG_TRACE("finishEvent: %p handled=%d, didDefaultHandling=%d", event,
            handled ? 1 : 0, didDefaultHandling ? 1 : 0);

    if (!handled && !didDefaultHandling
            && ((InputEvent*)event)->getType() == AINPUT_EVENT_TYPE_KEY
            && ((KeyEvent*)event)->hasDefaultAction()) {
        // The app didn't handle this, but it may have a default action
        // associated with it.  We need to hand this back to Java to be
        // executed.
        doUnhandledKey((KeyEvent*)event);
        return;
    }

    Mutex::Autolock _l(mLock);

    const size_t N = mInFlightEvents.size();
    for (size_t i=0; i<N; i++) {
        const in_flight_event& inflight(mInFlightEvents[i]);
        if (inflight.event == event) {
            if (inflight.finishSeq) {
                status_t res = mConsumer.sendFinishedSignal(inflight.finishSeq, handled);
                if (res != android::OK) {
                    ALOGW("Failed to send finished signal on channel '%s'.  status=%d",
                            mConsumer.getChannel()->getName().string(), res);
                }
            }
            mPooledInputEventFactory.recycle(static_cast<InputEvent*>(event));
            mInFlightEvents.removeAt(i);
            return;
        }
    }

    ALOGW("finishEvent called for unknown event: %p", event);
}

void AInputQueue::dispatchEvent(android::KeyEvent* event) {
    Mutex::Autolock _l(mLock);

    LOG_TRACE("dispatchEvent: dispatching=%d write=%d\n", mDispatchingKeys.size(),
            mDispatchKeyWrite);
    mDispatchingKeys.add(event);
    wakeupDispatchLocked();
}

void AInputQueue::finishPreDispatch(int seq, bool handled) {
    Mutex::Autolock _l(mLock);

    LOG_TRACE("finishPreDispatch: seq=%d handled=%d\n", seq, handled ? 1 : 0);
    finish_pre_dispatch finish;
    finish.seq = seq;
    finish.handled = handled;
    mFinishPreDispatches.add(finish);
    wakeupDispatchLocked();
}

KeyEvent* AInputQueue::consumeUnhandledEvent() {
    Mutex::Autolock _l(mLock);

    KeyEvent* event = NULL;
    if (mUnhandledKeys.size() > 0) {
        event = mUnhandledKeys[0];
        mUnhandledKeys.removeAt(0);
    }

    LOG_TRACE("consumeUnhandledEvent: KeyEvent=%p", event);
    return event;
}

KeyEvent* AInputQueue::consumePreDispatchingEvent(int* outSeq) {
    Mutex::Autolock _l(mLock);

    KeyEvent* event = NULL;
    if (mPreDispatchingKeys.size() > 0) {
        const in_flight_event& inflight(mPreDispatchingKeys[0]);
        event = static_cast<KeyEvent*>(inflight.event);
        *outSeq = inflight.seq;
        mPreDispatchingKeys.removeAt(0);
    }

    LOG_TRACE("consumePreDispatchingEvent: KeyEvent=%p", event);
    return event;
}

KeyEvent* AInputQueue::createKeyEvent() {
    Mutex::Autolock _l(mLock);

    return mPooledInputEventFactory.createKeyEvent();
}

void AInputQueue::doUnhandledKey(KeyEvent* keyEvent) {
    Mutex::Autolock _l(mLock);

    LOG_TRACE("Unhandled key: pending=%d write=%d\n", mUnhandledKeys.size(), mWorkWrite);
    if (mUnhandledKeys.size() <= 0 && mWorkWrite >= 0) {
        write_work(mWorkWrite, CMD_DEF_KEY);
    }
    mUnhandledKeys.add(keyEvent);
}

bool AInputQueue::preDispatchKey(KeyEvent* keyEvent) {
    Mutex::Autolock _l(mLock);

    LOG_TRACE("preDispatch key: pending=%d write=%d\n", mPreDispatchingKeys.size(), mWorkWrite);
    const size_t N = mInFlightEvents.size();
    for (size_t i=0; i<N; i++) {
        in_flight_event& inflight(mInFlightEvents.editItemAt(i));
        if (inflight.event == keyEvent) {
            if (inflight.seq >= 0) {
                // This event has already been pre-dispatched!
                LOG_TRACE("Event already pre-dispatched!");
                return false;
            }
            mSeq++;
            if (mSeq < 0) mSeq = 1;
            inflight.seq = mSeq;

            if (mPreDispatchingKeys.size() <= 0 && mWorkWrite >= 0) {
                write_work(mWorkWrite, CMD_DEF_KEY);
            }
            mPreDispatchingKeys.add(inflight);
            return true;
        }
    }

    ALOGW("preDispatchKey called for unknown event: %p", keyEvent);
    return false;
}

void AInputQueue::wakeupDispatchLocked() {
restart:
    char dummy = 0;
    int res = write(mDispatchKeyWrite, &dummy, sizeof(dummy));
    if (res < 0 && errno == EINTR) {
        goto restart;
    }

    if (res == sizeof(dummy)) return;

    if (res < 0) ALOGW("Failed writing to dispatch fd: %s", strerror(errno));
    else ALOGW("Truncated writing to dispatch fd: %d", res);
}

namespace android {

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

/*
 * Native state for interacting with the NativeActivity class.
 */
struct NativeCode : public ANativeActivity {
    NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) {
        memset((ANativeActivity*)this, 0, sizeof(ANativeActivity));
        memset(&callbacks, 0, sizeof(callbacks));
        dlhandle = _dlhandle;
        createActivityFunc = _createFunc;
        nativeWindow = NULL;
        inputChannel = NULL;
        nativeInputQueue = NULL;
        mainWorkRead = mainWorkWrite = -1;
    }
    
    ~NativeCode() {
        if (callbacks.onDestroy != NULL) {
            callbacks.onDestroy(this);
        }
        if (env != NULL && clazz != NULL) {
            env->DeleteGlobalRef(clazz);
        }
        if (messageQueue != NULL && mainWorkRead >= 0) {
            messageQueue->getLooper()->removeFd(mainWorkRead);
        }
        if (nativeInputQueue != NULL) {
            nativeInputQueue->mWorkWrite = -1;
        }
        setSurface(NULL);
        setInputChannel(NULL);
        if (mainWorkRead >= 0) close(mainWorkRead);
        if (mainWorkWrite >= 0) close(mainWorkWrite);
        if (dlhandle != NULL) {
            // for now don't unload...  we probably should clean this
            // up and only keep one open dlhandle per proc, since there
            // is really no benefit to unloading the code.
            //dlclose(dlhandle);
        }
    }
    
    void setSurface(jobject _surface) {
        if (_surface != NULL) {
            nativeWindow = android_view_Surface_getNativeWindow(env, _surface);
        } else {
            nativeWindow = NULL;
        }
    }
    
    status_t setInputChannel(jobject _channel) {
        if (inputChannel != NULL) {
            delete nativeInputQueue;
            env->DeleteGlobalRef(inputChannel);
        }
        inputChannel = NULL;
        nativeInputQueue = NULL;
        if (_channel != NULL) {
            inputChannel = env->NewGlobalRef(_channel);
            sp<InputChannel> ic =
                    android_view_InputChannel_getInputChannel(env, _channel);
            if (ic != NULL) {
                nativeInputQueue = new AInputQueue(ic, mainWorkWrite);
            } else {
                return UNKNOWN_ERROR;
            }
        }
        return OK;
    }
    
    ANativeActivityCallbacks callbacks;
    
    void* dlhandle;
    ANativeActivity_createFunc* createActivityFunc;
    
    String8 internalDataPathObj;
    String8 externalDataPathObj;
    String8 obbPathObj;
    
    sp<ANativeWindow> nativeWindow;
    int32_t lastWindowWidth;
    int32_t lastWindowHeight;

    jobject inputChannel;
    struct AInputQueue* nativeInputQueue;
    
    // These are used to wake up the main thread to process work.
    int mainWorkRead;
    int mainWorkWrite;
    sp<MessageQueue> messageQueue;
};

void android_NativeActivity_finish(ANativeActivity* activity) {
    NativeCode* code = static_cast<NativeCode*>(activity);
    write_work(code->mainWorkWrite, CMD_FINISH, 0);
}

void android_NativeActivity_setWindowFormat(
        ANativeActivity* activity, int32_t format) {
    NativeCode* code = static_cast<NativeCode*>(activity);
    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FORMAT, format);
}

void android_NativeActivity_setWindowFlags(
        ANativeActivity* activity, int32_t values, int32_t mask) {
    NativeCode* code = static_cast<NativeCode*>(activity);
    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FLAGS, values, mask);
}

void android_NativeActivity_showSoftInput(
        ANativeActivity* activity, int32_t flags) {
    NativeCode* code = static_cast<NativeCode*>(activity);
    write_work(code->mainWorkWrite, CMD_SHOW_SOFT_INPUT, flags);
}

void android_NativeActivity_hideSoftInput(
        ANativeActivity* activity, int32_t flags) {
    NativeCode* code = static_cast<NativeCode*>(activity);
    write_work(code->mainWorkWrite, CMD_HIDE_SOFT_INPUT, flags);
}

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

/*
 * Callback for handling native events on the application's main thread.
 */
static int mainWorkCallback(int fd, int events, void* data) {
    NativeCode* code = (NativeCode*)data;
    if ((events & POLLIN) == 0) {
        return 1;
    }
    
    ActivityWork work;
    if (!read_work(code->mainWorkRead, &work)) {
        return 1;
    }

    LOG_TRACE("mainWorkCallback: cmd=%d", work.cmd);

    switch (work.cmd) {
        case CMD_DEF_KEY: {
            KeyEvent* keyEvent;
            while ((keyEvent=code->nativeInputQueue->consumeUnhandledEvent()) != NULL) {
                jobject inputEventObj = android_view_KeyEvent_fromNative(
                        code->env, keyEvent);
                jboolean handled;
                if (inputEventObj) {
                    handled = code->env->CallBooleanMethod(code->clazz,
                            gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
                    code->messageQueue->raiseAndClearException(
                            code->env, "dispatchUnhandledKeyEvent");
                    code->env->DeleteLocalRef(inputEventObj);
                } else {
                    ALOGE("Failed to obtain key event for dispatchUnhandledKeyEvent.");
                    handled = false;
                }
                code->nativeInputQueue->finishEvent(keyEvent, handled, true);
            }
            int seq;
            while ((keyEvent=code->nativeInputQueue->consumePreDispatchingEvent(&seq)) != NULL) {
                jobject inputEventObj = android_view_KeyEvent_fromNative(
                        code->env, keyEvent);
                if (inputEventObj) {
                    code->env->CallVoidMethod(code->clazz,
                            gNativeActivityClassInfo.preDispatchKeyEvent, inputEventObj, seq);
                    code->messageQueue->raiseAndClearException(code->env, "preDispatchKeyEvent");
                    code->env->DeleteLocalRef(inputEventObj);
                } else {
                    ALOGE("Failed to obtain key event for preDispatchKeyEvent.");
                }
            }
        } break;
        case CMD_FINISH: {
            code->env->CallVoidMethod(code->clazz, gNativeActivityClassInfo.finish);
            code->messageQueue->raiseAndClearException(code->env, "finish");
        } break;
        case CMD_SET_WINDOW_FORMAT: {
            code->env->CallVoidMethod(code->clazz,
                    gNativeActivityClassInfo.setWindowFormat, work.arg1);
            code->messageQueue->raiseAndClearException(code->env, "setWindowFormat");
        } break;
        case CMD_SET_WINDOW_FLAGS: {
            code->env->CallVoidMethod(code->clazz,
                    gNativeActivityClassInfo.setWindowFlags, work.arg1, work.arg2);
            code->messageQueue->raiseAndClearException(code->env, "setWindowFlags");
        } break;
        case CMD_SHOW_SOFT_INPUT: {
            code->env->CallVoidMethod(code->clazz,
                    gNativeActivityClassInfo.showIme, work.arg1);
            code->messageQueue->raiseAndClearException(code->env, "showIme");
        } break;
        case CMD_HIDE_SOFT_INPUT: {
            code->env->CallVoidMethod(code->clazz,
                    gNativeActivityClassInfo.hideIme, work.arg1);
            code->messageQueue->raiseAndClearException(code->env, "hideIme");
        } break;
        default:
            ALOGW("Unknown work command: %d", work.cmd);
            break;
    }
    
    return 1;
}

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

static jint
loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName,
        jobject messageQueue, jstring internalDataDir, jstring obbDir,
        jstring externalDataDir, int sdkVersion,
        jobject jAssetMgr, jbyteArray savedState)
{
    LOG_TRACE("loadNativeCode_native");

    const char* pathStr = env->GetStringUTFChars(path, NULL);
    NativeCode* code = NULL;
    
    void* handle = dlopen(pathStr, RTLD_LAZY);
    
    env->ReleaseStringUTFChars(path, pathStr);
    
    if (handle != NULL) {
        const char* funcStr = env->GetStringUTFChars(funcName, NULL);
        code = new NativeCode(handle, (ANativeActivity_createFunc*)
                dlsym(handle, funcStr));
        env->ReleaseStringUTFChars(funcName, funcStr);
        
        if (code->createActivityFunc == NULL) {
            ALOGW("ANativeActivity_onCreate not found");
            delete code;
            return 0;
        }
        
        code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
        if (code->messageQueue == NULL) {
            ALOGW("Unable to retrieve native MessageQueue");
            delete code;
            return 0;
        }
        
        int msgpipe[2];
        if (pipe(msgpipe)) {
            ALOGW("could not create pipe: %s", strerror(errno));
            delete code;
            return 0;
        }
        code->mainWorkRead = msgpipe[0];
        code->mainWorkWrite = msgpipe[1];
        int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK);
        SLOGW_IF(result != 0, "Could not make main work read pipe "
                "non-blocking: %s", strerror(errno));
        result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
        SLOGW_IF(result != 0, "Could not make main work write pipe "
                "non-blocking: %s", strerror(errno));
        code->messageQueue->getLooper()->addFd(
                code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code);
        
        code->ANativeActivity::callbacks = &code->callbacks;
        if (env->GetJavaVM(&code->vm) < 0) {
            ALOGW("NativeActivity GetJavaVM failed");
            delete code;
            return 0;
        }
        code->env = env;
        code->clazz = env->NewGlobalRef(clazz);

        const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
        code->internalDataPathObj = dirStr;
        code->internalDataPath = code->internalDataPathObj.string();
        env->ReleaseStringUTFChars(internalDataDir, dirStr);
    
        dirStr = env->GetStringUTFChars(externalDataDir, NULL);
        code->externalDataPathObj = dirStr;
        code->externalDataPath = code->externalDataPathObj.string();
        env->ReleaseStringUTFChars(externalDataDir, dirStr);

        code->sdkVersion = sdkVersion;
        
        code->assetManager = assetManagerForJavaObject(env, jAssetMgr);

        dirStr = env->GetStringUTFChars(obbDir, NULL);
        code->obbPathObj = dirStr;
        code->obbPath = code->obbPathObj.string();
        env->ReleaseStringUTFChars(obbDir, dirStr);

        jbyte* rawSavedState = NULL;
        jsize rawSavedSize = 0;
        if (savedState != NULL) {
            rawSavedState = env->GetByteArrayElements(savedState, NULL);
            rawSavedSize = env->GetArrayLength(savedState);
        }

        code->createActivityFunc(code, rawSavedState, rawSavedSize);

        if (rawSavedState != NULL) {
            env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
        }
    }
    
    return (jint)code;
}

static void
unloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle)
{
    LOG_TRACE("unloadNativeCode_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        delete code;
    }
}

static void
onStart_native(JNIEnv* env, jobject clazz, jint handle)
{
    LOG_TRACE("onStart_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->callbacks.onStart != NULL) {
            code->callbacks.onStart(code);
        }
    }
}

static void
onResume_native(JNIEnv* env, jobject clazz, jint handle)
{
    LOG_TRACE("onResume_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->callbacks.onResume != NULL) {
            code->callbacks.onResume(code);
        }
    }
}

static jbyteArray
onSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle)
{
    LOG_TRACE("onSaveInstanceState_native");

    jbyteArray array = NULL;

    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->callbacks.onSaveInstanceState != NULL) {
            size_t len = 0;
            jbyte* state = (jbyte*)code->callbacks.onSaveInstanceState(code, &len);
            if (len > 0) {
                array = env->NewByteArray(len);
                if (array != NULL) {
                    env->SetByteArrayRegion(array, 0, len, state);
                }
            }
            if (state != NULL) {
                free(state);
            }
        }
    }

    return array;
}

static void
onPause_native(JNIEnv* env, jobject clazz, jint handle)
{
    LOG_TRACE("onPause_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->callbacks.onPause != NULL) {
            code->callbacks.onPause(code);
        }
    }
}

static void
onStop_native(JNIEnv* env, jobject clazz, jint handle)
{
    LOG_TRACE("onStop_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->callbacks.onStop != NULL) {
            code->callbacks.onStop(code);
        }
    }
}

static void
onConfigurationChanged_native(JNIEnv* env, jobject clazz, jint handle)
{
    LOG_TRACE("onConfigurationChanged_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->callbacks.onConfigurationChanged != NULL) {
            code->callbacks.onConfigurationChanged(code);
        }
    }
}

static void
onLowMemory_native(JNIEnv* env, jobject clazz, jint handle)
{
    LOG_TRACE("onLowMemory_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->callbacks.onLowMemory != NULL) {
            code->callbacks.onLowMemory(code);
        }
    }
}

static void
onWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean focused)
{
    LOG_TRACE("onWindowFocusChanged_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->callbacks.onWindowFocusChanged != NULL) {
            code->callbacks.onWindowFocusChanged(code, focused ? 1 : 0);
        }
    }
}

static void
onSurfaceCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
{
    LOG_TRACE("onSurfaceCreated_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        code->setSurface(surface);
        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
            code->callbacks.onNativeWindowCreated(code,
                    code->nativeWindow.get());
        }
    }
}

static int32_t getWindowProp(ANativeWindow* window, int what) {
    int value;
    int res = window->query(window, what, &value);
    return res < 0 ? res : value;
}

static void
onSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface,
        jint format, jint width, jint height)
{
    LOG_TRACE("onSurfaceChanged_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        sp<ANativeWindow> oldNativeWindow = code->nativeWindow;
        code->setSurface(surface);
        if (oldNativeWindow != code->nativeWindow) {
            if (oldNativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
                code->callbacks.onNativeWindowDestroyed(code,
                        oldNativeWindow.get());
            }
            if (code->nativeWindow != NULL) {
                if (code->callbacks.onNativeWindowCreated != NULL) {
                    code->callbacks.onNativeWindowCreated(code,
                            code->nativeWindow.get());
                }
                code->lastWindowWidth = getWindowProp(code->nativeWindow.get(),
                        NATIVE_WINDOW_WIDTH);
                code->lastWindowHeight = getWindowProp(code->nativeWindow.get(),
                        NATIVE_WINDOW_HEIGHT);
            }
        } else {
            // Maybe it resized?
            int32_t newWidth = getWindowProp(code->nativeWindow.get(),
                    NATIVE_WINDOW_WIDTH);
            int32_t newHeight = getWindowProp(code->nativeWindow.get(),
                    NATIVE_WINDOW_HEIGHT);
            if (newWidth != code->lastWindowWidth
                    || newHeight != code->lastWindowHeight) {
                if (code->callbacks.onNativeWindowResized != NULL) {
                    code->callbacks.onNativeWindowResized(code,
                            code->nativeWindow.get());
                }
            }
        }
    }
}

static void
onSurfaceRedrawNeeded_native(JNIEnv* env, jobject clazz, jint handle)
{
    LOG_TRACE("onSurfaceRedrawNeeded_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowRedrawNeeded != NULL) {
            code->callbacks.onNativeWindowRedrawNeeded(code, code->nativeWindow.get());
        }
    }
}

static void
onSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
{
    LOG_TRACE("onSurfaceDestroyed_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
            code->callbacks.onNativeWindowDestroyed(code,
                    code->nativeWindow.get());
        }
        code->setSurface(NULL);
    }
}

static void
onInputChannelCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
{
    LOG_TRACE("onInputChannelCreated_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        status_t err = code->setInputChannel(channel);
        if (err != OK) {
            jniThrowException(env, "java/lang/IllegalStateException",
                    "Error setting input channel");
            return;
        }
        if (code->callbacks.onInputQueueCreated != NULL) {
            code->callbacks.onInputQueueCreated(code,
                    code->nativeInputQueue);
        }
    }
}

static void
onInputChannelDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
{
    LOG_TRACE("onInputChannelDestroyed_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->nativeInputQueue != NULL
                && code->callbacks.onInputQueueDestroyed != NULL) {
            code->callbacks.onInputQueueDestroyed(code,
                    code->nativeInputQueue);
        }
        code->setInputChannel(NULL);
    }
}

static void
onContentRectChanged_native(JNIEnv* env, jobject clazz, jint handle,
        jint x, jint y, jint w, jint h)
{
    LOG_TRACE("onContentRectChanged_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->callbacks.onContentRectChanged != NULL) {
            ARect rect;
            rect.left = x;
            rect.top = y;
            rect.right = x+w;
            rect.bottom = y+h;
            code->callbacks.onContentRectChanged(code, &rect);
        }
    }
}

static void
dispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle, jobject eventObj)
{
    LOG_TRACE("dispatchKeyEvent_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->nativeInputQueue != NULL) {
            KeyEvent* event = code->nativeInputQueue->createKeyEvent();
            status_t status = android_view_KeyEvent_toNative(env, eventObj, event);
            if (status) {
                delete event;
                jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
                return;
            }
            code->nativeInputQueue->dispatchEvent(event);
        }
    }
}

static void
finishPreDispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle,
        jint seq, jboolean handled)
{
    LOG_TRACE("finishPreDispatchKeyEvent_native");
    if (handle != 0) {
        NativeCode* code = (NativeCode*)handle;
        if (code->nativeInputQueue != NULL) {
            code->nativeInputQueue->finishPreDispatch(seq, handled ? true : false);
        }
    }
}

static const JNINativeMethod g_methods[] = {
    { "loadNativeCode", "(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)I",
            (void*)loadNativeCode_native },
    { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
    { "onStartNative", "(I)V", (void*)onStart_native },
    { "onResumeNative", "(I)V", (void*)onResume_native },
    { "onSaveInstanceStateNative", "(I)[B", (void*)onSaveInstanceState_native },
    { "onPauseNative", "(I)V", (void*)onPause_native },
    { "onStopNative", "(I)V", (void*)onStop_native },
    { "onConfigurationChangedNative", "(I)V", (void*)onConfigurationChanged_native },
    { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native },
    { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native },
    { "onSurfaceCreatedNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceCreated_native },
    { "onSurfaceChangedNative", "(ILandroid/view/Surface;III)V", (void*)onSurfaceChanged_native },
    { "onSurfaceRedrawNeededNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceRedrawNeeded_native },
    { "onSurfaceDestroyedNative", "(I)V", (void*)onSurfaceDestroyed_native },
    { "onInputChannelCreatedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelCreated_native },
    { "onInputChannelDestroyedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelDestroyed_native },
    { "onContentRectChangedNative", "(IIIII)V", (void*)onContentRectChanged_native },
    { "dispatchKeyEventNative", "(ILandroid/view/KeyEvent;)V", (void*)dispatchKeyEvent_native },
    { "finishPreDispatchKeyEventNative", "(IIZ)V", (void*)finishPreDispatchKeyEvent_native },
};

static const char* const kNativeActivityPathName = "android/app/NativeActivity";

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

#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
        LOG_FATAL_IF(! var, "Unable to find method" methodName);
        
int register_android_app_NativeActivity(JNIEnv* env)
{
    //ALOGD("register_android_app_NativeActivity");
    jclass clazz;
    FIND_CLASS(clazz, kNativeActivityPathName);

    GET_METHOD_ID(gNativeActivityClassInfo.dispatchUnhandledKeyEvent,
            clazz,
            "dispatchUnhandledKeyEvent", "(Landroid/view/KeyEvent;)Z");
    GET_METHOD_ID(gNativeActivityClassInfo.preDispatchKeyEvent,
            clazz,
            "preDispatchKeyEvent", "(Landroid/view/KeyEvent;I)V");

    GET_METHOD_ID(gNativeActivityClassInfo.finish,
            clazz,
            "finish", "()V");
    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFlags,
            clazz,
            "setWindowFlags", "(II)V");
    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFormat,
            clazz,
            "setWindowFormat", "(I)V");
    GET_METHOD_ID(gNativeActivityClassInfo.showIme,
            clazz,
            "showIme", "(I)V");
    GET_METHOD_ID(gNativeActivityClassInfo.hideIme,
            clazz,
            "hideIme", "(I)V");

    return AndroidRuntime::registerNativeMethods(
        env, kNativeActivityPathName,
        g_methods, NELEM(g_methods));
}

} // namespace android
