android_app_NativeActivity.cpp revision 54a181b1a2b1517a9479b21fbf7705a688232faf
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>
2554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn#include <surfaceflinger/Surface.h>
2654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn#include <ui/egl/android_natives.h>
27a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn#include <ui/InputTransport.h>
283c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include <utils/PollLoop.h>
2969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
303c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "JNIHelp.h"
313c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_os_MessageQueue.h"
323c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_InputChannel.h"
333c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_KeyEvent.h"
3454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn#include "android_view_Surface.h"
3569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
3669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornnamespace android
3769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
3869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
393c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic struct {
403c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    jclass clazz;
413c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
423c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    jmethodID dispatchUnhandledKeyEvent;
4354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    jmethodID setWindowFlags;
4454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    jmethodID setWindowFormat;
453c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} gNativeActivityClassInfo;
463c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
4754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
4854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
4954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
5054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Specialized input queue that allows unhandled key events to be dispatched
5154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * back to the native activity's Java framework code.
5254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
533c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstruct MyInputQueue : AInputQueue {
543c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    explicit MyInputQueue(const android::sp<android::InputChannel>& channel, int workWrite)
553c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        : AInputQueue(channel), mWorkWrite(workWrite) {
563c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
573c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
583c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    virtual void doDefaultKey(android::KeyEvent* keyEvent) {
593c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.lock();
603c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOGI("Default key: pending=%d write=%d\n", mPendingKeys.size(), mWorkWrite);
613c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mPendingKeys.size() <= 0 && mWorkWrite >= 0) {
623c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            int8_t cmd = 1;
633c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            write(mWorkWrite, &cmd, sizeof(cmd));
643c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
653c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mPendingKeys.add(keyEvent);
663c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.unlock();
673c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
683c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
693c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    KeyEvent* getNextEvent() {
703c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        KeyEvent* event = NULL;
713c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
723c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.lock();
733c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mPendingKeys.size() > 0) {
743c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            event = mPendingKeys[0];
753c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            mPendingKeys.removeAt(0);
763c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
773c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.unlock();
783c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
793c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        return event;
803c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
813c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
823c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mWorkWrite;
833c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
843c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    Mutex mLock;
853c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    Vector<KeyEvent*> mPendingKeys;
863c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn};
873c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
8854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
8954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
9054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
9154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Native state for interacting with the NativeActivity class.
9254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
9369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstruct NativeCode {
942e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) {
9574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        memset(&activity, sizeof(activity), 0);
9674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        memset(&callbacks, sizeof(callbacks), 0);
9774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        dlhandle = _dlhandle;
9874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        createActivityFunc = _createFunc;
9954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        nativeWindow = NULL;
100a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
101a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
1023c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mainWorkRead = mainWorkWrite = -1;
10374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
10474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
10574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    ~NativeCode() {
1063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (activity.env != NULL && activity.clazz != NULL) {
1073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            activity.env->DeleteGlobalRef(activity.clazz);
1083c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pollLoop != NULL && mainWorkRead >= 0) {
1103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            pollLoop->removeCallback(mainWorkRead);
1113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1123c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (nativeInputQueue != NULL) {
1133c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            nativeInputQueue->mWorkWrite = -1;
1143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
115a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setSurface(NULL);
116a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setInputChannel(NULL);
11774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (callbacks.onDestroy != NULL) {
11874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn            callbacks.onDestroy(&activity);
11974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
1203c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkRead >= 0) close(mainWorkRead);
1213c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkWrite >= 0) close(mainWorkWrite);
12274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (dlhandle != NULL) {
12354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // for now don't unload...  we probably should clean this
12454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // up and only keep one open dlhandle per proc, since there
12554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // is really no benefit to unloading the code.
12654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            //dlclose(dlhandle);
12774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
12874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
12974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
13074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    void setSurface(jobject _surface) {
13174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (_surface != NULL) {
13254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            nativeWindow = android_Surface_getNativeWindow(activity.env, _surface);
13374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        } else {
13454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            nativeWindow = NULL;
13574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
13674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
13774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
138a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    status_t setInputChannel(jobject _channel) {
139a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (inputChannel != NULL) {
140a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            delete nativeInputQueue;
141a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            activity.env->DeleteGlobalRef(inputChannel);
142a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
143a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
144a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
145a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (_channel != NULL) {
146a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            inputChannel = activity.env->NewGlobalRef(_channel);
147a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            sp<InputChannel> ic =
148a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    android_view_InputChannel_getInputChannel(activity.env, _channel);
149a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            if (ic != NULL) {
1503c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                nativeInputQueue = new MyInputQueue(ic, mainWorkWrite);
151a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                if (nativeInputQueue->getConsumer().initialize() != android::OK) {
152a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    delete nativeInputQueue;
153a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    nativeInputQueue = NULL;
154a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    return UNKNOWN_ERROR;
155a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                }
156a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            } else {
157a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                return UNKNOWN_ERROR;
158a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            }
159a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
160a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        return OK;
161a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
162a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
1632e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivity activity;
1642e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivityCallbacks callbacks;
16569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
16669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* dlhandle;
1672e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivity_createFunc* createActivityFunc;
16874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
16954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    sp<ANativeWindow> nativeWindow;
170a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    jobject inputChannel;
1713c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    struct MyInputQueue* nativeInputQueue;
1723c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1733c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    // These are used to wake up the main thread to process work.
1743c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkRead;
1753c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkWrite;
1763c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    sp<PollLoop> pollLoop;
17769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
17869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
17954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
18054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
18154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
18254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Callback for handling native events on the application's main thread.
18354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
1843c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic bool mainWorkCallback(int fd, int events, void* data) {
1853c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    NativeCode* code = (NativeCode*)data;
1863c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    if ((events & POLLIN) != 0) {
1873c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        KeyEvent* keyEvent;
1883c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        while ((keyEvent=code->nativeInputQueue->getNextEvent()) != NULL) {
1893c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            jobject inputEventObj = android_view_KeyEvent_fromNative(
1903c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                    code->activity.env, keyEvent);
1913c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            code->activity.env->CallVoidMethod(code->activity.clazz,
1923c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                    gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
1933c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            int32_t res = code->nativeInputQueue->getConsumer().sendFinishedSignal();
1943c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            if (res != OK) {
1953c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                LOGW("Failed to send finished signal on channel '%s'.  status=%d",
1963c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                        code->nativeInputQueue->getConsumer().getChannel()->getName().string(), res);
1973c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            }
1983c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1993c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
2003c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2013c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return true;
2023c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
2033c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
20454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
20554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
20669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic jint
2073c80a4a044865bdf1289c7896baffa1c082d835cDianne HackbornloadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQueue)
20869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
20969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    const char* pathStr = env->GetStringUTFChars(path, NULL);
21069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    NativeCode* code = NULL;
21169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
21269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* handle = dlopen(pathStr, RTLD_LAZY);
21369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
21469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    env->ReleaseStringUTFChars(path, pathStr);
21569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
21669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != NULL) {
2172e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        code = new NativeCode(handle, (ANativeActivity_createFunc*)
2182e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn                dlsym(handle, "ANativeActivity_onCreate"));
21969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->createActivityFunc == NULL) {
2202e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("ANativeActivity_onCreate not found");
22169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            delete code;
22269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            return 0;
22369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
2243c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2253c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop = android_os_MessageQueue_getPollLoop(env, messageQueue);
2263c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (code->pollLoop == NULL) {
2273c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("Unable to retrieve MessageQueue's PollLoop");
2283c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
2293c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
2303c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
2313c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2323c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        int msgpipe[2];
2333c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pipe(msgpipe)) {
2343c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("could not create pipe: %s", strerror(errno));
2353c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
2363c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
2373c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
2383c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkRead = msgpipe[0];
2393c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkWrite = msgpipe[1];
2403c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop->setCallback(code->mainWorkRead, POLLIN, mainWorkCallback, code);
2413c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
24269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        code->activity.callbacks = &code->callbacks;
2432e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        if (env->GetJavaVM(&code->activity.vm) < 0) {
2442e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("NativeActivity GetJavaVM failed");
2452e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            delete code;
2462e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            return 0;
2472e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        }
24869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        code->activity.env = env;
2493c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->activity.clazz = env->NewGlobalRef(clazz);
25069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        code->createActivityFunc(&code->activity, NULL, 0);
25169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
25269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
25369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return (jint)code;
25469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
25569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
25669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
25769969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornunloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle)
25869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
25969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
26069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
26169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        delete code;
26269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
26369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
26469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
26569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
26669969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStart_native(JNIEnv* env, jobject clazz, jint handle)
26769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
26869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
26969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
27069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStart != NULL) {
27169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onStart(&code->activity);
27269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
27369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
27469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
27569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
27669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
27769969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonResume_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.onResume != NULL) {
28269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onResume(&code->activity);
28369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
28469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
28569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
28669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
28769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
28869969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonSaveInstanceState_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.onSaveInstanceState != NULL) {
29369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            size_t len = 0;
29469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onSaveInstanceState(&code->activity, &len);
29569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
29669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
29769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
29869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
29969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
30069969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonPause_native(JNIEnv* env, jobject clazz, jint handle)
30169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
30269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
30369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
30469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onPause != NULL) {
30569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onPause(&code->activity);
30669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
30769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
30869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
30969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
31069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
31169969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStop_native(JNIEnv* env, jobject clazz, jint handle)
31269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
31369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
31469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
31569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStop != NULL) {
31669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onStop(&code->activity);
31769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
31869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
31969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
32069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
32169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
32269969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonLowMemory_native(JNIEnv* env, jobject clazz, jint handle)
32369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
32469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
32569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
32669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onLowMemory != NULL) {
32769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onLowMemory(&code->activity);
32869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
32969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
33069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
33169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
33269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
33369969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean focused)
33469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
33569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
33669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
33769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onWindowFocusChanged != NULL) {
33869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            code->callbacks.onWindowFocusChanged(&code->activity, focused ? 1 : 0);
33969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
34069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
34169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
34269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
34374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
34474323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
34574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
34674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
34774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
34874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(surface);
34954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
35054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            code->callbacks.onNativeWindowCreated(&code->activity,
35154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
35274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
35374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
35474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
35574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
35674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
35774323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface,
35874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        jint format, jint width, jint height)
35974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
36074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
36174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
36254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        sp<ANativeWindow> oldNativeWindow = code->nativeWindow;
36354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        code->setSurface(surface);
36454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (oldNativeWindow != code->nativeWindow) {
36554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            if (code->nativeWindow != NULL && code->callbacks.onNativeWindowChanged != NULL) {
36654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                code->callbacks.onNativeWindowChanged(&code->activity,
36754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                        code->nativeWindow.get());
36854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            }
36974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
37074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
37174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
37274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
37374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
37474323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
37574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
37674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
37774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
37854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
37954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            code->callbacks.onNativeWindowDestroyed(&code->activity,
38054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
38174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
38274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(NULL);
38374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
38474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
38574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
386a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
387a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
388a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
389a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
390a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
391a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        status_t err = code->setInputChannel(channel);
392a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (err != OK) {
393a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            jniThrowException(env, "java/lang/IllegalStateException",
394a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    "Error setting input channel");
395a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            return;
396a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
397a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->callbacks.onInputQueueCreated != NULL) {
398a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            code->callbacks.onInputQueueCreated(&code->activity,
399a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
400a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
401a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
402a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
403a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
404a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
405a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
406a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
407a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
408a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
409a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->nativeInputQueue != NULL
410a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                && code->callbacks.onInputQueueDestroyed != NULL) {
411a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            code->callbacks.onInputQueueDestroyed(&code->activity,
412a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
413a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
414a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        code->setInputChannel(NULL);
415a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
416a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
417a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
41869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const JNINativeMethod g_methods[] = {
4193c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    { "loadNativeCode", "(Ljava/lang/String;Landroid/os/MessageQueue;)I", (void*)loadNativeCode_native },
42069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
42169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStartNative", "(I)V", (void*)onStart_native },
42269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onResumeNative", "(I)V", (void*)onResume_native },
42369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onSaveInstanceStateNative", "(I)V", (void*)onSaveInstanceState_native },
42469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onPauseNative", "(I)V", (void*)onPause_native },
42569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStopNative", "(I)V", (void*)onStop_native },
42669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native },
42769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native },
42854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceCreatedNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceCreated_native },
42954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceChangedNative", "(ILandroid/view/Surface;III)V", (void*)onSurfaceChanged_native },
43054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceDestroyedNative", "(I)V", (void*)onSurfaceDestroyed_native },
431a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelCreatedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelCreated_native },
432a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelDestroyedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelDestroyed_native },
43369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
43469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
43569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const char* const kNativeActivityPathName = "android/app/NativeActivity";
43669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
4373c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define FIND_CLASS(var, className) \
4383c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->FindClass(className); \
4393c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find class " className); \
4403c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = jclass(env->NewGlobalRef(var));
4413c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
4423c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
4433c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
4443c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find method" methodName);
4453c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
44669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornint register_android_app_NativeActivity(JNIEnv* env)
44769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
44869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    //LOGD("register_android_app_NativeActivity");
44969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
4503c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    FIND_CLASS(gNativeActivityClassInfo.clazz, kNativeActivityPathName);
45154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
4523c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.dispatchUnhandledKeyEvent,
4533c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            gNativeActivityClassInfo.clazz,
4543c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            "dispatchUnhandledKeyEvent", "(Landroid/view/KeyEvent;)V");
45554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
45654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFlags,
45754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            gNativeActivityClassInfo.clazz,
45854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFlags", "(II)V");
45954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFormat,
46054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            gNativeActivityClassInfo.clazz,
46154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFormat", "(I)V");
46254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
46369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return AndroidRuntime::registerNativeMethods(
46469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        env, kNativeActivityPathName,
46569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        g_methods, NELEM(g_methods));
46669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
46769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
468a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn} // namespace android
469