android_app_NativeActivity.cpp revision 289b9b62372ef52a06113b83dfb870e2c2fb325a
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>
24289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn#include <android_runtime/android_view_Surface.h>
25289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn#include <android_runtime/android_app_NativeActivity.h>
2654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn#include <surfaceflinger/Surface.h>
2754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn#include <ui/egl/android_natives.h>
28a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn#include <ui/InputTransport.h>
293c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include <utils/PollLoop.h>
3069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
313c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "JNIHelp.h"
323c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_os_MessageQueue.h"
333c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_InputChannel.h"
343c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_KeyEvent.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
49289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstruct ActivityWork {
50289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t cmd;
51289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t arg1;
52289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t arg2;
53289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn};
54289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
55289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornenum {
56289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_DEF_KEY = 1,
57289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_SET_WINDOW_FORMAT,
58289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_SET_WINDOW_FLAGS,
59289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn};
60289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
61289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstatic void write_work(int fd, int32_t cmd, int32_t arg1=0, int32_t arg2=0) {
62289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    ActivityWork work;
63289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.cmd = cmd;
64289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.arg1 = arg1;
65289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.arg2 = arg2;
66289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
67289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornrestart:
68289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int res = write(fd, &work, sizeof(work));
69289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0 && errno == EINTR) {
70289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        goto restart;
71289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
72289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
73289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res == sizeof(work)) return;
74289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
75289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0) LOGW("Failed writing to work fd: %s", strerror(errno));
76289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    else LOGW("Truncated writing to work fd: %d", res);
77289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
78289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
79289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstatic bool read_work(int fd, ActivityWork* outWork) {
80289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int res = read(fd, outWork, sizeof(ActivityWork));
81289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    // no need to worry about EINTR, poll loop will just come back again.
82289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res == sizeof(ActivityWork)) return true;
83289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
84289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0) LOGW("Failed reading work fd: %s", strerror(errno));
85289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    else LOGW("Truncated reading work fd: %d", res);
86289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    return false;
87289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
88289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
89289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn// ------------------------------------------------------------------------
90289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
9154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
9254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Specialized input queue that allows unhandled key events to be dispatched
9354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * back to the native activity's Java framework code.
9454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
953c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstruct MyInputQueue : AInputQueue {
963c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    explicit MyInputQueue(const android::sp<android::InputChannel>& channel, int workWrite)
973c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        : AInputQueue(channel), mWorkWrite(workWrite) {
983c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
993c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1003c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    virtual void doDefaultKey(android::KeyEvent* keyEvent) {
1013c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.lock();
1023c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOGI("Default key: pending=%d write=%d\n", mPendingKeys.size(), mWorkWrite);
1033c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mPendingKeys.size() <= 0 && mWorkWrite >= 0) {
104289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            write_work(mWorkWrite, CMD_DEF_KEY);
1053c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mPendingKeys.add(keyEvent);
1073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.unlock();
1083c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
1093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    KeyEvent* getNextEvent() {
1113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        KeyEvent* event = NULL;
1123c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1133c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.lock();
1143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mPendingKeys.size() > 0) {
1153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            event = mPendingKeys[0];
1163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            mPendingKeys.removeAt(0);
1173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.unlock();
1193c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1203c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        return event;
1213c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
1223c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1233c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mWorkWrite;
1243c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1253c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    Mutex mLock;
1263c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    Vector<KeyEvent*> mPendingKeys;
1273c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn};
1283c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
12954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
13054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
13154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
13254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Native state for interacting with the NativeActivity class.
13354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
134289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstruct NativeCode : public ANativeActivity {
1352e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) {
136289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        memset((ANativeActivity*)this, sizeof(ANativeActivity), 0);
13774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        memset(&callbacks, sizeof(callbacks), 0);
13874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        dlhandle = _dlhandle;
13974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        createActivityFunc = _createFunc;
14054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        nativeWindow = NULL;
141a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
142a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
1433c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mainWorkRead = mainWorkWrite = -1;
14474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
14574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
14674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    ~NativeCode() {
147289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (callbacks.onDestroy != NULL) {
148289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            callbacks.onDestroy(this);
149289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        }
150289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (env != NULL && clazz != NULL) {
151289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            env->DeleteGlobalRef(clazz);
1523c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1533c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pollLoop != NULL && mainWorkRead >= 0) {
1543c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            pollLoop->removeCallback(mainWorkRead);
1553c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1563c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (nativeInputQueue != NULL) {
1573c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            nativeInputQueue->mWorkWrite = -1;
1583c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
159a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setSurface(NULL);
160a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setInputChannel(NULL);
1613c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkRead >= 0) close(mainWorkRead);
1623c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkWrite >= 0) close(mainWorkWrite);
16374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (dlhandle != NULL) {
16454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // for now don't unload...  we probably should clean this
16554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // up and only keep one open dlhandle per proc, since there
16654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // is really no benefit to unloading the code.
16754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            //dlclose(dlhandle);
16874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
16974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
17074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
17174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    void setSurface(jobject _surface) {
17274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (_surface != NULL) {
173289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            nativeWindow = android_Surface_getNativeWindow(env, _surface);
17474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        } else {
17554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            nativeWindow = NULL;
17674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
17774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
17874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
179a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    status_t setInputChannel(jobject _channel) {
180a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (inputChannel != NULL) {
181a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            delete nativeInputQueue;
182289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            env->DeleteGlobalRef(inputChannel);
183a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
184a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
185a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
186a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (_channel != NULL) {
187289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            inputChannel = env->NewGlobalRef(_channel);
188a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            sp<InputChannel> ic =
189289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    android_view_InputChannel_getInputChannel(env, _channel);
190a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            if (ic != NULL) {
1913c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn                nativeInputQueue = new MyInputQueue(ic, mainWorkWrite);
192a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                if (nativeInputQueue->getConsumer().initialize() != android::OK) {
193a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    delete nativeInputQueue;
194a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    nativeInputQueue = NULL;
195a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    return UNKNOWN_ERROR;
196a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                }
197a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            } else {
198a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                return UNKNOWN_ERROR;
199a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            }
200a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
201a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        return OK;
202a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
203a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
2042e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivityCallbacks callbacks;
20569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
20669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* dlhandle;
2072e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivity_createFunc* createActivityFunc;
20874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
209682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn    String8 internalDataPath;
210682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn    String8 externalDataPath;
211682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
21254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    sp<ANativeWindow> nativeWindow;
213a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    jobject inputChannel;
2143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    struct MyInputQueue* nativeInputQueue;
2153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    // These are used to wake up the main thread to process work.
2173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkRead;
2183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkWrite;
2193c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    sp<PollLoop> pollLoop;
22069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
22169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
222289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornvoid android_NativeActivity_setWindowFormat(
223289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        ANativeActivity* activity, int32_t format) {
224289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
225289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FORMAT, format);
226289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
227289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
228289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornvoid android_NativeActivity_setWindowFlags(
229289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        ANativeActivity* activity, int32_t values, int32_t mask) {
230289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
231289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FLAGS, values, mask);
232289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
233289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
23454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
23554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
23654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
23754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Callback for handling native events on the application's main thread.
23854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
2393c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic bool mainWorkCallback(int fd, int events, void* data) {
2403c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    NativeCode* code = (NativeCode*)data;
241289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if ((events & POLLIN) == 0) {
242289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        return true;
243289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
244289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
245289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    ActivityWork work;
246289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (!read_work(code->mainWorkRead, &work)) {
247289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        return true;
248289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
249289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    switch (work.cmd) {
250289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_DEF_KEY: {
251289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            KeyEvent* keyEvent;
252289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            while ((keyEvent=code->nativeInputQueue->getNextEvent()) != NULL) {
253289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                jobject inputEventObj = android_view_KeyEvent_fromNative(
254289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                        code->env, keyEvent);
255289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                code->env->CallVoidMethod(code->clazz,
256289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                        gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
257289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                int32_t res = code->nativeInputQueue->getConsumer().sendFinishedSignal();
258289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                if (res != OK) {
259289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    LOGW("Failed to send finished signal on channel '%s'.  status=%d",
260289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                            code->nativeInputQueue->getConsumer().getChannel()->getName().string(), res);
261289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                }
2623c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            }
263289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
264289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_SET_WINDOW_FORMAT: {
265289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->env->CallVoidMethod(code->clazz,
266289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    gNativeActivityClassInfo.setWindowFormat, work.arg1);
267289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
268289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_SET_WINDOW_FLAGS: {
269289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->env->CallVoidMethod(code->clazz,
270289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    gNativeActivityClassInfo.setWindowFlags, work.arg1, work.arg2);
271289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
272289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        default:
273289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            LOGW("Unknown work command: %d", work.cmd);
274289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            break;
2753c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
2763c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2773c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return true;
2783c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
2793c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
28054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
28154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
28269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic jint
283682674154e3fe88f6061245145f934f25f1a2eb8Dianne HackbornloadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQueue,
284682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        jstring internalDataDir, jstring externalDataDir, int sdkVersion)
28569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
28669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    const char* pathStr = env->GetStringUTFChars(path, NULL);
28769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    NativeCode* code = NULL;
28869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
28969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* handle = dlopen(pathStr, RTLD_LAZY);
29069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
29169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    env->ReleaseStringUTFChars(path, pathStr);
29269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
29369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != NULL) {
2942e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        code = new NativeCode(handle, (ANativeActivity_createFunc*)
2952e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn                dlsym(handle, "ANativeActivity_onCreate"));
29669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->createActivityFunc == NULL) {
2972e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("ANativeActivity_onCreate not found");
29869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            delete code;
29969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            return 0;
30069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
3013c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
3023c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop = android_os_MessageQueue_getPollLoop(env, messageQueue);
3033c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (code->pollLoop == NULL) {
3043c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("Unable to retrieve MessageQueue's PollLoop");
3053c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
3063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
3073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
3083c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
3093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        int msgpipe[2];
3103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pipe(msgpipe)) {
3113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("could not create pipe: %s", strerror(errno));
3123c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
3133c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
3143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
3153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkRead = msgpipe[0];
3163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkWrite = msgpipe[1];
3173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop->setCallback(code->mainWorkRead, POLLIN, mainWorkCallback, code);
3183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
319289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->ANativeActivity::callbacks = &code->callbacks;
320289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (env->GetJavaVM(&code->vm) < 0) {
3212e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("NativeActivity GetJavaVM failed");
3222e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            delete code;
3232e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            return 0;
3242e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        }
325289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->env = env;
326289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->clazz = env->NewGlobalRef(clazz);
327682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
328682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
329682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        code->internalDataPath = dirStr;
330289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->internalDataPath = code->internalDataPath.string();
331682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        env->ReleaseStringUTFChars(path, dirStr);
332682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
333682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        dirStr = env->GetStringUTFChars(externalDataDir, NULL);
334682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        code->externalDataPath = dirStr;
335289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->externalDataPath = code->externalDataPath.string();
336682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        env->ReleaseStringUTFChars(path, dirStr);
337682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
338289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->sdkVersion = sdkVersion;
339682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
340289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->createActivityFunc(code, NULL, 0);
34169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
34269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
34369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return (jint)code;
34469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
34569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
34669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
34769969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornunloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle)
34869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
34969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
35069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
35169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        delete code;
35269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
35369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
35469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
35569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
35669969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStart_native(JNIEnv* env, jobject clazz, jint handle)
35769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
35869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
35969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
36069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStart != NULL) {
361289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onStart(code);
36269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
36369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
36469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
36569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
36669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
36769969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonResume_native(JNIEnv* env, jobject clazz, jint handle)
36869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
36969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
37069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
37169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onResume != NULL) {
372289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onResume(code);
37369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
37469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
37569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
37669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
37769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
37869969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle)
37969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
38069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
38169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
38269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onSaveInstanceState != NULL) {
38369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            size_t len = 0;
384289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onSaveInstanceState(code, &len);
38569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
38669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
38769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
38869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
38969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
39069969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonPause_native(JNIEnv* env, jobject clazz, jint handle)
39169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
39269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
39369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
39469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onPause != NULL) {
395289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onPause(code);
39669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
39769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
39869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
39969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
40069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
40169969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStop_native(JNIEnv* env, jobject clazz, jint handle)
40269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
40369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
40469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
40569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStop != NULL) {
406289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onStop(code);
40769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
40869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
40969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
41069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
41169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
41269969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonLowMemory_native(JNIEnv* env, jobject clazz, jint handle)
41369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
41469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
41569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
41669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onLowMemory != NULL) {
417289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onLowMemory(code);
41869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
41969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
42069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
42169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
42269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
42369969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean focused)
42469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
42569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
42669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
42769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onWindowFocusChanged != NULL) {
428289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onWindowFocusChanged(code, focused ? 1 : 0);
42969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
43069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
43169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
43269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
43374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
43474323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
43574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
43674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
43774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
43874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(surface);
43954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
440289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onNativeWindowCreated(code,
44154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
44274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
44374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
44474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
44574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
44674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
44774323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface,
44874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        jint format, jint width, jint height)
44974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
45074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
45174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
45254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        sp<ANativeWindow> oldNativeWindow = code->nativeWindow;
45354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        code->setSurface(surface);
45454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (oldNativeWindow != code->nativeWindow) {
4558ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn            if (oldNativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
456289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                code->callbacks.onNativeWindowDestroyed(code,
4578ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn                        oldNativeWindow.get());
4588ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn            }
4598ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn            if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
460289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                code->callbacks.onNativeWindowCreated(code,
46154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                        code->nativeWindow.get());
46254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            }
46374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
46474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
46574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
46674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
46774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
46874323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
46974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
47074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
47174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
47254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
473289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onNativeWindowDestroyed(code,
47454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
47574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
47674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(NULL);
47774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
47874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
47974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
480a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
481a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
482a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
483a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
484a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
485a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        status_t err = code->setInputChannel(channel);
486a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (err != OK) {
487a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            jniThrowException(env, "java/lang/IllegalStateException",
488a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    "Error setting input channel");
489a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            return;
490a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
491a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->callbacks.onInputQueueCreated != NULL) {
492289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onInputQueueCreated(code,
493a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
494a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
495a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
496a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
497a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
498a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
499a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
500a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
501a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
502a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
503a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->nativeInputQueue != NULL
504a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                && code->callbacks.onInputQueueDestroyed != NULL) {
505289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onInputQueueDestroyed(code,
506a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
507a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
508a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        code->setInputChannel(NULL);
509a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
510a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
511a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
51269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const JNINativeMethod g_methods[] = {
513682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn    { "loadNativeCode", "(Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;I)I",
514682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn            (void*)loadNativeCode_native },
51569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
51669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStartNative", "(I)V", (void*)onStart_native },
51769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onResumeNative", "(I)V", (void*)onResume_native },
51869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onSaveInstanceStateNative", "(I)V", (void*)onSaveInstanceState_native },
51969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onPauseNative", "(I)V", (void*)onPause_native },
52069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStopNative", "(I)V", (void*)onStop_native },
52169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native },
52269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native },
52354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceCreatedNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceCreated_native },
52454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceChangedNative", "(ILandroid/view/Surface;III)V", (void*)onSurfaceChanged_native },
52554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceDestroyedNative", "(I)V", (void*)onSurfaceDestroyed_native },
526a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelCreatedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelCreated_native },
527a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelDestroyedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelDestroyed_native },
52869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
52969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
53069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const char* const kNativeActivityPathName = "android/app/NativeActivity";
53169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
5323c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define FIND_CLASS(var, className) \
5333c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->FindClass(className); \
5343c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find class " className); \
5353c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = jclass(env->NewGlobalRef(var));
5363c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
5373c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
5383c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
5393c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find method" methodName);
5403c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
54169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornint register_android_app_NativeActivity(JNIEnv* env)
54269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
54369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    //LOGD("register_android_app_NativeActivity");
54469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
5453c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    FIND_CLASS(gNativeActivityClassInfo.clazz, kNativeActivityPathName);
54654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
5473c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.dispatchUnhandledKeyEvent,
5483c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            gNativeActivityClassInfo.clazz,
5493c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            "dispatchUnhandledKeyEvent", "(Landroid/view/KeyEvent;)V");
55054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
55154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFlags,
55254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            gNativeActivityClassInfo.clazz,
55354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFlags", "(II)V");
55454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFormat,
55554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            gNativeActivityClassInfo.clazz,
55654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFormat", "(I)V");
55754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
55869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return AndroidRuntime::registerNativeMethods(
55969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        env, kNativeActivityPathName,
56069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        g_methods, NELEM(g_methods));
56169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
56269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
563a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn} // namespace android
564