android_app_NativeActivity.cpp revision 3c80a4a044865bdf1289c7896baffa1c082d835c
169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn/*
269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * Copyright (C) 2010 The Android Open Source Project
369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn *
469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * you may not use this file except in compliance with the License.
669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * You may obtain a copy of the License at
769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn *
869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn *
1069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * Unless required by applicable law or agreed to in writing, software
1169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
1269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * See the License for the specific language governing permissions and
1469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn * limitations under the License.
1569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn */
1669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
1769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn#define LOG_TAG "NativeActivity"
1869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn#include <utils/Log.h>
1969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
203c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include <poll.h>
213c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include <dlfcn.h>
223c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn#include <android_runtime/AndroidRuntime.h>
2469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn#include <android/native_activity.h>
25a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn#include <ui/InputTransport.h>
263c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include <utils/PollLoop.h>
2769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
283c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "JNIHelp.h"
293c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_os_MessageQueue.h"
303c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_InputChannel.h"
313c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_KeyEvent.h"
3269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
3369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornnamespace android
3469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
3569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
363c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic struct {
373c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    jclass clazz;
383c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
393c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    jmethodID dispatchUnhandledKeyEvent;
403c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} gNativeActivityClassInfo;
413c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
423c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstruct MyInputQueue : AInputQueue {
433c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    explicit MyInputQueue(const android::sp<android::InputChannel>& channel, int workWrite)
443c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        : AInputQueue(channel), mWorkWrite(workWrite) {
453c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
463c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
473c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    virtual void doDefaultKey(android::KeyEvent* keyEvent) {
483c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.lock();
493c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOGI("Default key: pending=%d write=%d\n", mPendingKeys.size(), mWorkWrite);
503c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mPendingKeys.size() <= 0 && mWorkWrite >= 0) {
513c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            int8_t cmd = 1;
523c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            write(mWorkWrite, &cmd, sizeof(cmd));
533c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
543c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mPendingKeys.add(keyEvent);
553c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.unlock();
563c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
573c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
583c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    KeyEvent* getNextEvent() {
593c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        KeyEvent* event = NULL;
603c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
613c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.lock();
623c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mPendingKeys.size() > 0) {
633c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            event = mPendingKeys[0];
643c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            mPendingKeys.removeAt(0);
653c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
663c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.unlock();
673c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
683c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        return event;
693c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
703c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
713c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mWorkWrite;
723c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
733c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    Mutex mLock;
743c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    Vector<KeyEvent*> mPendingKeys;
753c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn};
763c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
7769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstruct NativeCode {
782e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) {
7974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        memset(&activity, sizeof(activity), 0);
8074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        memset(&callbacks, sizeof(callbacks), 0);
8174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        dlhandle = _dlhandle;
8274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        createActivityFunc = _createFunc;
8374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        surface = NULL;
84a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
85a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
863c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mainWorkRead = mainWorkWrite = -1;
8774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
8874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
8974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    ~NativeCode() {
903c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (activity.env != NULL && activity.clazz != NULL) {
913c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            activity.env->DeleteGlobalRef(activity.clazz);
923c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
933c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pollLoop != NULL && mainWorkRead >= 0) {
943c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            pollLoop->removeCallback(mainWorkRead);
953c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
963c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (nativeInputQueue != NULL) {
973c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            nativeInputQueue->mWorkWrite = -1;
983c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
99a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setSurface(NULL);
100a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setInputChannel(NULL);
10174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (callbacks.onDestroy != NULL) {
10274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn            callbacks.onDestroy(&activity);
10374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
1043c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkRead >= 0) close(mainWorkRead);
1053c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkWrite >= 0) close(mainWorkWrite);
10674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (dlhandle != NULL) {
10774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn            dlclose(dlhandle);
10874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
10974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
11074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
11174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    void setSurface(jobject _surface) {
11274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (surface != NULL) {
11374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn            activity.env->DeleteGlobalRef(surface);
11474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
11574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (_surface != NULL) {
11674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn            surface = activity.env->NewGlobalRef(_surface);
11774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        } else {
11874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn            surface = NULL;
11974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
12074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
12174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
122a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    status_t setInputChannel(jobject _channel) {
123a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (inputChannel != NULL) {
124a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            delete nativeInputQueue;
125a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            activity.env->DeleteGlobalRef(inputChannel);
126a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
127a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
128a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
129a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (_channel != NULL) {
130a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            inputChannel = activity.env->NewGlobalRef(_channel);
131a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            sp<InputChannel> ic =
132a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    android_view_InputChannel_getInputChannel(activity.env, _channel);
133a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            if (ic != NULL) {
1343c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                nativeInputQueue = new MyInputQueue(ic, mainWorkWrite);
135a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                if (nativeInputQueue->getConsumer().initialize() != android::OK) {
136a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    delete nativeInputQueue;
137a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    nativeInputQueue = NULL;
138a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    return UNKNOWN_ERROR;
139a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                }
140a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            } else {
141a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                return UNKNOWN_ERROR;
142a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            }
143a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
144a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        return OK;
145a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
146a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
1472e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivity activity;
1482e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivityCallbacks callbacks;
14969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
15069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* dlhandle;
1512e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivity_createFunc* createActivityFunc;
15274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
15374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    jobject surface;
154a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    jobject inputChannel;
1553c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    struct MyInputQueue* nativeInputQueue;
1563c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1573c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    // These are used to wake up the main thread to process work.
1583c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkRead;
1593c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkWrite;
1603c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    sp<PollLoop> pollLoop;
16169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
16269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
1633c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic bool mainWorkCallback(int fd, int events, void* data) {
1643c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    NativeCode* code = (NativeCode*)data;
1653c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    if ((events & POLLIN) != 0) {
1663c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        KeyEvent* keyEvent;
1673c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        while ((keyEvent=code->nativeInputQueue->getNextEvent()) != NULL) {
1683c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            jobject inputEventObj = android_view_KeyEvent_fromNative(
1693c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                    code->activity.env, keyEvent);
1703c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            code->activity.env->CallVoidMethod(code->activity.clazz,
1713c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                    gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
1723c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            int32_t res = code->nativeInputQueue->getConsumer().sendFinishedSignal();
1733c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            if (res != OK) {
1743c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                LOGW("Failed to send finished signal on channel '%s'.  status=%d",
1753c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                        code->nativeInputQueue->getConsumer().getChannel()->getName().string(), res);
1763c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            }
1773c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1783c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
1793c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1803c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return true;
1813c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
1823c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
18369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic jint
1843c80a4a044865bdf1289c7896baffa1c082d835cDianne HackbornloadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQueue)
18569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
18669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    const char* pathStr = env->GetStringUTFChars(path, NULL);
18769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    NativeCode* code = NULL;
18869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
18969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* handle = dlopen(pathStr, RTLD_LAZY);
19069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
19169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    env->ReleaseStringUTFChars(path, pathStr);
19269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
19369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != NULL) {
1942e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        code = new NativeCode(handle, (ANativeActivity_createFunc*)
1952e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn                dlsym(handle, "ANativeActivity_onCreate"));
19669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->createActivityFunc == NULL) {
1972e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("ANativeActivity_onCreate not found");
19869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            delete code;
19969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            return 0;
20069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
2013c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2023c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop = android_os_MessageQueue_getPollLoop(env, messageQueue);
2033c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (code->pollLoop == NULL) {
2043c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("Unable to retrieve MessageQueue's PollLoop");
2053c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
2063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
2073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
2083c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        int msgpipe[2];
2103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pipe(msgpipe)) {
2113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("could not create pipe: %s", strerror(errno));
2123c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
2133c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
2143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
2153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkRead = msgpipe[0];
2163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkWrite = msgpipe[1];
2173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop->setCallback(code->mainWorkRead, POLLIN, mainWorkCallback, code);
2183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
21969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        code->activity.callbacks = &code->callbacks;
2202e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        if (env->GetJavaVM(&code->activity.vm) < 0) {
2212e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("NativeActivity GetJavaVM failed");
2222e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            delete code;
2232e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            return 0;
2242e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        }
22569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        code->activity.env = env;
2263c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->activity.clazz = env->NewGlobalRef(clazz);
22769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        code->createActivityFunc(&code->activity, NULL, 0);
22869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
22969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
23069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return (jint)code;
23169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
23269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
23369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
23469969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornunloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle)
23569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
23669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
23769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
23869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        delete code;
23969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
24069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
24169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
24269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
24369969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStart_native(JNIEnv* env, jobject clazz, jint handle)
24469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
24569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
24669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
24769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStart != NULL) {
24869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onStart(&code->activity);
24969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
25069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
25169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
25269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
25369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
25469969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonResume_native(JNIEnv* env, jobject clazz, jint handle)
25569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
25669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
25769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
25869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onResume != NULL) {
25969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onResume(&code->activity);
26069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
26169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
26269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
26369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
26469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
26569969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle)
26669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
26769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
26869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
26969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onSaveInstanceState != NULL) {
27069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            size_t len = 0;
27169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onSaveInstanceState(&code->activity, &len);
27269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
27369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
27469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
27569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
27669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
27769969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonPause_native(JNIEnv* env, jobject clazz, jint handle)
27869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
27969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
28069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
28169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onPause != NULL) {
28269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onPause(&code->activity);
28369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
28469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
28569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
28669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
28769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
28869969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStop_native(JNIEnv* env, jobject clazz, jint handle)
28969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
29069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
29169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
29269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStop != NULL) {
29369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onStop(&code->activity);
29469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
29569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
29669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
29769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
29869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
29969969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonLowMemory_native(JNIEnv* env, jobject clazz, jint handle)
30069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
30169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
30269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
30369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onLowMemory != NULL) {
30469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onLowMemory(&code->activity);
30569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
30669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
30769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
30869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
30969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
31069969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean focused)
31169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
31269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
31369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
31469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onWindowFocusChanged != NULL) {
31569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onWindowFocusChanged(&code->activity, focused ? 1 : 0);
31669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
31769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
31869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
31969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
32074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
32174323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
32274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
32374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
32474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
32574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(surface);
32674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (code->callbacks.onSurfaceCreated != NULL) {
32774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn            code->callbacks.onSurfaceCreated(&code->activity,
3282e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn                    (ASurfaceHolder*)code->surface);
32974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
33074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
33174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
33274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
33374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
33474323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface,
33574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        jint format, jint width, jint height)
33674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
33774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
33874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
33974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (code->surface != NULL && code->callbacks.onSurfaceChanged != NULL) {
34074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn            code->callbacks.onSurfaceChanged(&code->activity,
3412e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn                    (ASurfaceHolder*)code->surface, format, width, height);
34274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
34374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
34474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
34574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
34674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
34774323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
34874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
34974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
35074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
35174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (code->surface != NULL && code->callbacks.onSurfaceDestroyed != NULL) {
35274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn            code->callbacks.onSurfaceDestroyed(&code->activity,
3532e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn                    (ASurfaceHolder*)code->surface);
35474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
35574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(NULL);
35674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
35774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
35874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
359a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
360a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
361a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
362a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
363a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
364a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        status_t err = code->setInputChannel(channel);
365a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (err != OK) {
366a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            jniThrowException(env, "java/lang/IllegalStateException",
367a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    "Error setting input channel");
368a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            return;
369a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
370a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->callbacks.onInputQueueCreated != NULL) {
371a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            code->callbacks.onInputQueueCreated(&code->activity,
372a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
373a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
374a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
375a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
376a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
377a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
378a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
379a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
380a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
381a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
382a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->nativeInputQueue != NULL
383a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                && code->callbacks.onInputQueueDestroyed != NULL) {
384a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            code->callbacks.onInputQueueDestroyed(&code->activity,
385a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
386a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
387a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        code->setInputChannel(NULL);
388a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
389a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
390a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
39169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const JNINativeMethod g_methods[] = {
3923c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    { "loadNativeCode", "(Ljava/lang/String;Landroid/os/MessageQueue;)I", (void*)loadNativeCode_native },
39369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
39469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStartNative", "(I)V", (void*)onStart_native },
39569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onResumeNative", "(I)V", (void*)onResume_native },
39669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onSaveInstanceStateNative", "(I)V", (void*)onSaveInstanceState_native },
39769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onPauseNative", "(I)V", (void*)onPause_native },
39869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStopNative", "(I)V", (void*)onStop_native },
39969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native },
40069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native },
40174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    { "onSurfaceCreatedNative", "(ILandroid/view/SurfaceHolder;)V", (void*)onSurfaceCreated_native },
40274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    { "onSurfaceChangedNative", "(ILandroid/view/SurfaceHolder;III)V", (void*)onSurfaceChanged_native },
40374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    { "onSurfaceDestroyedNative", "(ILandroid/view/SurfaceHolder;)V", (void*)onSurfaceDestroyed_native },
404a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelCreatedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelCreated_native },
405a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelDestroyedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelDestroyed_native },
40669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
40769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
40869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const char* const kNativeActivityPathName = "android/app/NativeActivity";
40969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
4103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define FIND_CLASS(var, className) \
4113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->FindClass(className); \
4123c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find class " className); \
4133c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = jclass(env->NewGlobalRef(var));
4143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
4153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
4163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
4173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find method" methodName);
4183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
41969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornint register_android_app_NativeActivity(JNIEnv* env)
42069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
42169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    //LOGD("register_android_app_NativeActivity");
42269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
4233c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    FIND_CLASS(gNativeActivityClassInfo.clazz, kNativeActivityPathName);
4243c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
4253c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.dispatchUnhandledKeyEvent,
4263c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            gNativeActivityClassInfo.clazz,
4273c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            "dispatchUnhandledKeyEvent", "(Landroid/view/KeyEvent;)V");
4283c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
42969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return AndroidRuntime::registerNativeMethods(
43069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        env, kNativeActivityPathName,
43169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        g_methods, NELEM(g_methods));
43269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
43369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
434a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn} // namespace android
435