android_app_NativeActivity.cpp revision 6cce32b6adbb3a9725fc730ba0e0068a74657e60
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>
22d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn#include <fcntl.h>
233c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn#include <android_runtime/AndroidRuntime.h>
25289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn#include <android_runtime/android_view_Surface.h>
26289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn#include <android_runtime/android_app_NativeActivity.h>
276cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate#include <android_runtime/android_util_AssetManager.h>
2854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn#include <surfaceflinger/Surface.h>
2954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn#include <ui/egl/android_natives.h>
30a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn#include <ui/InputTransport.h>
313c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include <utils/PollLoop.h>
3269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
333c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "JNIHelp.h"
343c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_os_MessageQueue.h"
353c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_InputChannel.h"
363c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_KeyEvent.h"
3769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
38d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn//#define LOG_TRACE(...)
39d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn#define LOG_TRACE(...) LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
40d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
4169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornnamespace android
4269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
4369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
443c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic struct {
453c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    jclass clazz;
463c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
473c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    jmethodID dispatchUnhandledKeyEvent;
4854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    jmethodID setWindowFlags;
4954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    jmethodID setWindowFormat;
50d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    jmethodID showIme;
51d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    jmethodID hideIme;
523c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} gNativeActivityClassInfo;
533c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
5454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
5554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
56289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstruct ActivityWork {
57289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t cmd;
58289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t arg1;
59289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t arg2;
60289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn};
61289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
62289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornenum {
63289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_DEF_KEY = 1,
64289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_SET_WINDOW_FORMAT,
65289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_SET_WINDOW_FLAGS,
66d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    CMD_SHOW_SOFT_INPUT,
67d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    CMD_HIDE_SOFT_INPUT,
68289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn};
69289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
70289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstatic void write_work(int fd, int32_t cmd, int32_t arg1=0, int32_t arg2=0) {
71289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    ActivityWork work;
72289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.cmd = cmd;
73289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.arg1 = arg1;
74289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.arg2 = arg2;
75289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
76d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("write_work: cmd=%d", cmd);
77d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
78289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornrestart:
79289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int res = write(fd, &work, sizeof(work));
80289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0 && errno == EINTR) {
81289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        goto restart;
82289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
83289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
84289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res == sizeof(work)) return;
85289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
86289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0) LOGW("Failed writing to work fd: %s", strerror(errno));
87289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    else LOGW("Truncated writing to work fd: %d", res);
88289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
89289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
90289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstatic bool read_work(int fd, ActivityWork* outWork) {
91289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int res = read(fd, outWork, sizeof(ActivityWork));
92289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    // no need to worry about EINTR, poll loop will just come back again.
93289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res == sizeof(ActivityWork)) return true;
94289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
95289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0) LOGW("Failed reading work fd: %s", strerror(errno));
96289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    else LOGW("Truncated reading work fd: %d", res);
97289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    return false;
98289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
99289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
100289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn// ------------------------------------------------------------------------
101289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
102d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn} // namespace android
103d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
104d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornusing namespace android;
105d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
106d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornAInputQueue::AInputQueue(const sp<InputChannel>& channel, int workWrite) :
107d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mWorkWrite(workWrite), mConsumer(channel) {
108d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int msgpipe[2];
109d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (pipe(msgpipe)) {
110d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        LOGW("could not create pipe: %s", strerror(errno));
111d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mDispatchKeyRead = mDispatchKeyWrite = -1;
112d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    } else {
113d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mDispatchKeyRead = msgpipe[0];
114d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mDispatchKeyWrite = msgpipe[1];
115d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        int result = fcntl(mDispatchKeyRead, F_SETFL, O_NONBLOCK);
116d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make AInputQueue read pipe "
117d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
118d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        result = fcntl(mDispatchKeyWrite, F_SETFL, O_NONBLOCK);
119d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make AInputQueue write pipe "
120d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
1213c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
122d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
123d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
124d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornAInputQueue::~AInputQueue() {
125d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    close(mDispatchKeyRead);
126d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    close(mDispatchKeyWrite);
127d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
128d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
129d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::attachLooper(ALooper* looper, ALooper_callbackFunc* callback, void* data) {
130d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop = static_cast<android::PollLoop*>(looper);
131d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop->setLooperCallback(mConsumer.getChannel()->getReceivePipeFd(),
132d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            POLLIN, callback, data);
133d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop->setLooperCallback(mDispatchKeyRead,
134d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            POLLIN, callback, data);
135d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
136d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
137d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::detachLooper() {
138d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop->removeCallback(mConsumer.getChannel()->getReceivePipeFd());
139d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop->removeCallback(mDispatchKeyRead);
140d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
141d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
142d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornint32_t AInputQueue::hasEvents() {
143d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    struct pollfd pfd[2];
144d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
145d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].fd = mConsumer.getChannel()->getReceivePipeFd();
146d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].events = POLLIN;
147d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].revents = 0;
148d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[1].fd = mDispatchKeyRead;
149d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].events = POLLIN;
150d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].revents = 0;
1513c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
152d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int nfd = poll(pfd, 2, 0);
153d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (nfd <= 0) return 0;
154d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return (pfd[0].revents == POLLIN || pfd[1].revents == POLLIN) ? 1 : -1;
155d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
156d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
157d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornint32_t AInputQueue::getEvent(AInputEvent** outEvent) {
158d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    *outEvent = NULL;
159d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
160d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    char byteread;
161d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    ssize_t nRead = read(mDispatchKeyRead, &byteread, 1);
162d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (nRead == 1) {
1633c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.lock();
164d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (mDispatchingKeys.size() > 0) {
165d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            KeyEvent* kevent = mDispatchingKeys[0];
166d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            *outEvent = kevent;
167d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            mDispatchingKeys.removeAt(0);
168d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            mDeliveringKeys.add(kevent);
1693c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1703c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.unlock();
171d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (*outEvent != NULL) {
172d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            return 0;
173d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
1743c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
1753c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
176d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int32_t res = mConsumer.receiveDispatchSignal();
177d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (res != android::OK) {
178d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        LOGE("channel '%s' ~ Failed to receive dispatch signal.  status=%d",
179d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                mConsumer.getChannel()->getName().string(), res);
180d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        return -1;
181d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
182d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
183d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    InputEvent* myEvent = NULL;
184d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    res = mConsumer.consume(&mInputEventFactory, &myEvent);
185d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (res != android::OK) {
186d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        LOGW("channel '%s' ~ Failed to consume input event.  status=%d",
187d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                mConsumer.getChannel()->getName().string(), res);
188d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mConsumer.sendFinishedSignal();
189d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        return -1;
190d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
191d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
192d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    *outEvent = myEvent;
193d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return 0;
194d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
195d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
196d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::finishEvent(AInputEvent* event, bool handled) {
197d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    bool needFinished = true;
198d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
199d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (!handled && ((InputEvent*)event)->getType() == INPUT_EVENT_TYPE_KEY
200d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            && ((KeyEvent*)event)->hasDefaultAction()) {
201d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        // The app didn't handle this, but it may have a default action
202d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        // associated with it.  We need to hand this back to Java to be
203d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        // executed.
204d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        doDefaultKey((KeyEvent*)event);
205d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        needFinished = false;
206d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
207d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
208d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    const size_t N = mDeliveringKeys.size();
209d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    for (size_t i=0; i<N; i++) {
210d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (mDeliveringKeys[i] == event) {
211d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            delete event;
212d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            mDeliveringKeys.removeAt(i);
213d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            needFinished = false;
214d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            break;
2153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
2163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
2173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
218d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (needFinished) {
219d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        int32_t res = mConsumer.sendFinishedSignal();
220d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (res != android::OK) {
221d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            LOGW("Failed to send finished signal on channel '%s'.  status=%d",
222d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    mConsumer.getChannel()->getName().string(), res);
223d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
224d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
225d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
226d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
227d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::dispatchEvent(android::KeyEvent* event) {
228d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.lock();
229d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("dispatchEvent: dispatching=%d write=%d\n", mDispatchingKeys.size(),
230d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            mDispatchKeyWrite);
231d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mDispatchingKeys.add(event);
232d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.unlock();
2333c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
234d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornrestart:
235d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    char dummy = 0;
236d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int res = write(mDispatchKeyWrite, &dummy, sizeof(dummy));
237d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (res < 0 && errno == EINTR) {
238d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        goto restart;
239d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
240d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
241d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (res == sizeof(dummy)) return;
242d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
243d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (res < 0) LOGW("Failed writing to dispatch fd: %s", strerror(errno));
244d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    else LOGW("Truncated writing to dispatch fd: %d", res);
245d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
246d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
247d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornKeyEvent* AInputQueue::consumeUnhandledEvent() {
248d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    KeyEvent* event = NULL;
249d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
250d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.lock();
251d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (mPendingKeys.size() > 0) {
252d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        event = mPendingKeys[0];
253d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mPendingKeys.removeAt(0);
254d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
255d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.unlock();
256d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
257d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("consumeUnhandledEvent: KeyEvent=%p", event);
258d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
259d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return event;
260d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
261d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
262d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::doDefaultKey(KeyEvent* keyEvent) {
263d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.lock();
264d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("Default key: pending=%d write=%d\n", mPendingKeys.size(), mWorkWrite);
265d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (mPendingKeys.size() <= 0 && mWorkWrite >= 0) {
266d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        write_work(mWorkWrite, CMD_DEF_KEY);
267d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
268d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPendingKeys.add(keyEvent);
269d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.unlock();
270d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
271d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
272d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornnamespace android {
2733c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
27454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
27554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
27654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
27754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Native state for interacting with the NativeActivity class.
27854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
279289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstruct NativeCode : public ANativeActivity {
2802e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) {
281d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        memset((ANativeActivity*)this, 0, sizeof(ANativeActivity));
282d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        memset(&callbacks, 0, sizeof(callbacks));
28374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        dlhandle = _dlhandle;
28474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        createActivityFunc = _createFunc;
28554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        nativeWindow = NULL;
286a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
287a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
2883c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mainWorkRead = mainWorkWrite = -1;
28974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
29074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
29174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    ~NativeCode() {
292289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (callbacks.onDestroy != NULL) {
293289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            callbacks.onDestroy(this);
294289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        }
295289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (env != NULL && clazz != NULL) {
296289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            env->DeleteGlobalRef(clazz);
2973c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
2983c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pollLoop != NULL && mainWorkRead >= 0) {
2993c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            pollLoop->removeCallback(mainWorkRead);
3003c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
3013c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (nativeInputQueue != NULL) {
3023c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            nativeInputQueue->mWorkWrite = -1;
3033c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
304a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setSurface(NULL);
305a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setInputChannel(NULL);
3063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkRead >= 0) close(mainWorkRead);
3073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkWrite >= 0) close(mainWorkWrite);
30874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (dlhandle != NULL) {
30954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // for now don't unload...  we probably should clean this
31054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // up and only keep one open dlhandle per proc, since there
31154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // is really no benefit to unloading the code.
31254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            //dlclose(dlhandle);
31374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
31474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
31574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
31674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    void setSurface(jobject _surface) {
31774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (_surface != NULL) {
318289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            nativeWindow = android_Surface_getNativeWindow(env, _surface);
31974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        } else {
32054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            nativeWindow = NULL;
32174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
32274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
32374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
324a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    status_t setInputChannel(jobject _channel) {
325a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (inputChannel != NULL) {
326a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            delete nativeInputQueue;
327289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            env->DeleteGlobalRef(inputChannel);
328a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
329a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
330a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
331a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (_channel != NULL) {
332289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            inputChannel = env->NewGlobalRef(_channel);
333a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            sp<InputChannel> ic =
334289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    android_view_InputChannel_getInputChannel(env, _channel);
335a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            if (ic != NULL) {
336d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                nativeInputQueue = new AInputQueue(ic, mainWorkWrite);
337a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                if (nativeInputQueue->getConsumer().initialize() != android::OK) {
338a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    delete nativeInputQueue;
339a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    nativeInputQueue = NULL;
340a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    return UNKNOWN_ERROR;
341a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                }
342a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            } else {
343a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                return UNKNOWN_ERROR;
344a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            }
345a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
346a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        return OK;
347a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
348a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
3492e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivityCallbacks callbacks;
35069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
35169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* dlhandle;
3522e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivity_createFunc* createActivityFunc;
35374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
354682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn    String8 internalDataPath;
355682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn    String8 externalDataPath;
356682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
35754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    sp<ANativeWindow> nativeWindow;
358d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int32_t lastWindowWidth;
359d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int32_t lastWindowHeight;
360d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
361a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    jobject inputChannel;
362d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    struct AInputQueue* nativeInputQueue;
3633c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
3643c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    // These are used to wake up the main thread to process work.
3653c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkRead;
3663c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkWrite;
3673c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    sp<PollLoop> pollLoop;
36869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
36969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
370289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornvoid android_NativeActivity_setWindowFormat(
371289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        ANativeActivity* activity, int32_t format) {
372289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
373289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FORMAT, format);
374289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
375289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
376289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornvoid android_NativeActivity_setWindowFlags(
377289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        ANativeActivity* activity, int32_t values, int32_t mask) {
378289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
379289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FLAGS, values, mask);
380289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
381289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
382d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid android_NativeActivity_showSoftInput(
383d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        ANativeActivity* activity, int32_t flags) {
384d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
385d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    write_work(code->mainWorkWrite, CMD_SHOW_SOFT_INPUT, flags);
386d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
387d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
388d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid android_NativeActivity_hideSoftInput(
389d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        ANativeActivity* activity, int32_t flags) {
390d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
391d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    write_work(code->mainWorkWrite, CMD_HIDE_SOFT_INPUT, flags);
392d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
393d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
39454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
39554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
39654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
39754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Callback for handling native events on the application's main thread.
39854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
3993c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic bool mainWorkCallback(int fd, int events, void* data) {
4003c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    NativeCode* code = (NativeCode*)data;
401289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if ((events & POLLIN) == 0) {
402289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        return true;
403289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
404289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
405289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    ActivityWork work;
406289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (!read_work(code->mainWorkRead, &work)) {
407289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        return true;
408289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
409d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
410d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("mainWorkCallback: cmd=%d", work.cmd);
411d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
412289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    switch (work.cmd) {
413289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_DEF_KEY: {
414289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            KeyEvent* keyEvent;
415d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            while ((keyEvent=code->nativeInputQueue->consumeUnhandledEvent()) != NULL) {
416289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                jobject inputEventObj = android_view_KeyEvent_fromNative(
417289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                        code->env, keyEvent);
418289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                code->env->CallVoidMethod(code->clazz,
419289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                        gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
420289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                int32_t res = code->nativeInputQueue->getConsumer().sendFinishedSignal();
421289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                if (res != OK) {
422289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    LOGW("Failed to send finished signal on channel '%s'.  status=%d",
423289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                            code->nativeInputQueue->getConsumer().getChannel()->getName().string(), res);
424289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                }
4253c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            }
426289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
427289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_SET_WINDOW_FORMAT: {
428289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->env->CallVoidMethod(code->clazz,
429289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    gNativeActivityClassInfo.setWindowFormat, work.arg1);
430289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
431289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_SET_WINDOW_FLAGS: {
432289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->env->CallVoidMethod(code->clazz,
433289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    gNativeActivityClassInfo.setWindowFlags, work.arg1, work.arg2);
434289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
435d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        case CMD_SHOW_SOFT_INPUT: {
436d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->env->CallVoidMethod(code->clazz,
437d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    gNativeActivityClassInfo.showIme, work.arg1);
438d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        } break;
439d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        case CMD_HIDE_SOFT_INPUT: {
440d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->env->CallVoidMethod(code->clazz,
441d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    gNativeActivityClassInfo.hideIme, work.arg1);
442d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        } break;
443289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        default:
444289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            LOGW("Unknown work command: %d", work.cmd);
445289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            break;
4463c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
4473c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
4483c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return true;
4493c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
4503c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
45154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
45254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
45369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic jint
454682674154e3fe88f6061245145f934f25f1a2eb8Dianne HackbornloadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQueue,
4556cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate        jstring internalDataDir, jstring externalDataDir, int sdkVersion,
4566cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate        jobject jAssetMgr)
45769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
458d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("loadNativeCode_native");
459d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
46069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    const char* pathStr = env->GetStringUTFChars(path, NULL);
46169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    NativeCode* code = NULL;
46269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
46369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* handle = dlopen(pathStr, RTLD_LAZY);
46469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
46569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    env->ReleaseStringUTFChars(path, pathStr);
46669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
46769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != NULL) {
4682e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        code = new NativeCode(handle, (ANativeActivity_createFunc*)
4692e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn                dlsym(handle, "ANativeActivity_onCreate"));
47069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->createActivityFunc == NULL) {
4712e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("ANativeActivity_onCreate not found");
47269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            delete code;
47369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            return 0;
47469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
4753c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
4763c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop = android_os_MessageQueue_getPollLoop(env, messageQueue);
4773c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (code->pollLoop == NULL) {
4783c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("Unable to retrieve MessageQueue's PollLoop");
4793c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
4803c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
4813c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
4823c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
4833c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        int msgpipe[2];
4843c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pipe(msgpipe)) {
4853c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("could not create pipe: %s", strerror(errno));
4863c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
4873c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
4883c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
4893c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkRead = msgpipe[0];
4903c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkWrite = msgpipe[1];
491d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK);
492d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make main work read pipe "
493d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
494d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
495d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make main work write pipe "
496d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
4973c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop->setCallback(code->mainWorkRead, POLLIN, mainWorkCallback, code);
4983c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
499289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->ANativeActivity::callbacks = &code->callbacks;
500289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (env->GetJavaVM(&code->vm) < 0) {
5012e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("NativeActivity GetJavaVM failed");
5022e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            delete code;
5032e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            return 0;
5042e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        }
505289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->env = env;
506289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->clazz = env->NewGlobalRef(clazz);
5076cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate
508682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
509682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        code->internalDataPath = dirStr;
510289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->internalDataPath = code->internalDataPath.string();
511682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        env->ReleaseStringUTFChars(path, dirStr);
512682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
513682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        dirStr = env->GetStringUTFChars(externalDataDir, NULL);
514682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        code->externalDataPath = dirStr;
515289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->externalDataPath = code->externalDataPath.string();
516682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        env->ReleaseStringUTFChars(path, dirStr);
5176cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate
518289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->sdkVersion = sdkVersion;
519682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
5206cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate        code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
5216cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate
522289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->createActivityFunc(code, NULL, 0);
52369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
52469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
52569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return (jint)code;
52669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
52769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
52869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
52969969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornunloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle)
53069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
531d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("unloadNativeCode_native");
53269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
53369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
53469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        delete code;
53569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
53669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
53769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
53869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
53969969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStart_native(JNIEnv* env, jobject clazz, jint handle)
54069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
541d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onStart_native");
54269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
54369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
54469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStart != NULL) {
545289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onStart(code);
54669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
54769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
54869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
54969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
55069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
55169969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonResume_native(JNIEnv* env, jobject clazz, jint handle)
55269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
553d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onResume_native");
55469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
55569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
55669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onResume != NULL) {
557289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onResume(code);
55869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
55969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
56069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
56169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
56269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
56369969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle)
56469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
565d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSaveInstanceState_native");
56669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
56769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
56869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onSaveInstanceState != NULL) {
56969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            size_t len = 0;
570289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onSaveInstanceState(code, &len);
57169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
57269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
57369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
57469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
57569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
57669969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonPause_native(JNIEnv* env, jobject clazz, jint handle)
57769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
578d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onPause_native");
57969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
58069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
58169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onPause != NULL) {
582289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onPause(code);
58369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
58469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
58569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
58669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
58769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
58869969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStop_native(JNIEnv* env, jobject clazz, jint handle)
58969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
590d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onStop_native");
59169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
59269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
59369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStop != NULL) {
594289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onStop(code);
59569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
59669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
59769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
59869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
59969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
60069969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonLowMemory_native(JNIEnv* env, jobject clazz, jint handle)
60169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
602d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onLowMemory_native");
60369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
60469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
60569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onLowMemory != NULL) {
606289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onLowMemory(code);
60769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
60869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
60969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
61069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
61169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
61269969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean focused)
61369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
614d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onWindowFocusChanged_native");
61569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
61669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
61769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onWindowFocusChanged != NULL) {
618289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onWindowFocusChanged(code, focused ? 1 : 0);
61969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
62069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
62169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
62269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
62374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
62474323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
62574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
626d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceCreated_native");
62774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
62874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
62974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(surface);
63054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
631289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onNativeWindowCreated(code,
63254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
63374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
63474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
63574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
63674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
637d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic int32_t getWindowProp(ANativeWindow* window, int what) {
638d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int value;
639d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int res = window->query(window, what, &value);
640d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return res < 0 ? res : value;
641d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
642d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
64374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
64474323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface,
64574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        jint format, jint width, jint height)
64674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
647d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceChanged_native");
64874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
64974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
65054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        sp<ANativeWindow> oldNativeWindow = code->nativeWindow;
65154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        code->setSurface(surface);
65254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (oldNativeWindow != code->nativeWindow) {
6538ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn            if (oldNativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
654289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                code->callbacks.onNativeWindowDestroyed(code,
6558ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn                        oldNativeWindow.get());
6568ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn            }
657d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            if (code->nativeWindow != NULL) {
658d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                if (code->callbacks.onNativeWindowCreated != NULL) {
659d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    code->callbacks.onNativeWindowCreated(code,
660d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                            code->nativeWindow.get());
661d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                }
662d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                code->lastWindowWidth = getWindowProp(code->nativeWindow.get(),
663d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                        NATIVE_WINDOW_WIDTH);
664d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                code->lastWindowHeight = getWindowProp(code->nativeWindow.get(),
665d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                        NATIVE_WINDOW_HEIGHT);
666d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            }
667d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        } else {
668d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            // Maybe it resized?
669d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            int32_t newWidth = getWindowProp(code->nativeWindow.get(),
670d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    NATIVE_WINDOW_WIDTH);
671d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            int32_t newHeight = getWindowProp(code->nativeWindow.get(),
672d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    NATIVE_WINDOW_HEIGHT);
673d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            if (newWidth != code->lastWindowWidth
674d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    || newHeight != code->lastWindowHeight) {
675d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                if (code->callbacks.onNativeWindowResized != NULL) {
676d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    code->callbacks.onNativeWindowResized(code,
677d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                            code->nativeWindow.get());
678d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                }
67954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            }
68074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
68174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
68274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
68374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
68474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
685d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornonSurfaceRedrawNeeded_native(JNIEnv* env, jobject clazz, jint handle)
686d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn{
687d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceRedrawNeeded_native");
688d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (handle != 0) {
689d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
690d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowRedrawNeeded != NULL) {
691d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->callbacks.onNativeWindowRedrawNeeded(code, code->nativeWindow.get());
692d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
693d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
694d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
695d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
696d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic void
69774323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
69874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
699d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceDestroyed_native");
70074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
70174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
70254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
703289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onNativeWindowDestroyed(code,
70454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
70574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
70674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(NULL);
70774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
70874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
70974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
710a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
711a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
712a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
713d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onInputChannelCreated_native");
714a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
715a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
716a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        status_t err = code->setInputChannel(channel);
717a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (err != OK) {
718a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            jniThrowException(env, "java/lang/IllegalStateException",
719a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    "Error setting input channel");
720a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            return;
721a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
722a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->callbacks.onInputQueueCreated != NULL) {
723289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onInputQueueCreated(code,
724a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
725a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
726a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
727a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
728a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
729a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
730a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
731a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
732d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onInputChannelDestroyed_native");
733a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
734a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
735a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->nativeInputQueue != NULL
736a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                && code->callbacks.onInputQueueDestroyed != NULL) {
737289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onInputQueueDestroyed(code,
738a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
739a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
740a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        code->setInputChannel(NULL);
741a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
742a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
743a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
744d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic void
745d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornonContentRectChanged_native(JNIEnv* env, jobject clazz, jint handle,
746d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        jint x, jint y, jint w, jint h)
747d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn{
748d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onContentRectChanged_native");
749d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (handle != 0) {
750d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
751d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (code->callbacks.onContentRectChanged != NULL) {
752d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            ARect rect;
753d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.left = x;
754d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.top = y;
755d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.right = x+w;
756d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.bottom = y+h;
757d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->callbacks.onContentRectChanged(code, &rect);
758d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
759d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
760d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
761d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
762d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic void
763d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackborndispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle, jobject eventObj)
764d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn{
765d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("dispatchKeyEvent_native");
766d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (handle != 0) {
767d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
768d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (code->nativeInputQueue != NULL) {
769d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            KeyEvent* event = new KeyEvent();
770d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            android_view_KeyEvent_toNative(env, eventObj, INPUT_EVENT_NATURE_KEY, event);
771d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->nativeInputQueue->dispatchEvent(event);
772d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
773d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
774d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
775d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
77669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const JNINativeMethod g_methods[] = {
7776cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate    { "loadNativeCode", "(Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;I;Landroid/content/res/AssetManager)I",
778682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn            (void*)loadNativeCode_native },
77969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
78069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStartNative", "(I)V", (void*)onStart_native },
78169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onResumeNative", "(I)V", (void*)onResume_native },
78269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onSaveInstanceStateNative", "(I)V", (void*)onSaveInstanceState_native },
78369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onPauseNative", "(I)V", (void*)onPause_native },
78469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStopNative", "(I)V", (void*)onStop_native },
78569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native },
78669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native },
78754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceCreatedNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceCreated_native },
78854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceChangedNative", "(ILandroid/view/Surface;III)V", (void*)onSurfaceChanged_native },
789d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    { "onSurfaceRedrawNeededNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceRedrawNeeded_native },
79054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceDestroyedNative", "(I)V", (void*)onSurfaceDestroyed_native },
791a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelCreatedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelCreated_native },
792a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelDestroyedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelDestroyed_native },
793d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    { "onContentRectChangedNative", "(IIIII)V", (void*)onContentRectChanged_native },
794d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    { "dispatchKeyEventNative", "(ILandroid/view/KeyEvent;)V", (void*)dispatchKeyEvent_native },
79569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
79669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
79769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const char* const kNativeActivityPathName = "android/app/NativeActivity";
79869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
7993c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define FIND_CLASS(var, className) \
8003c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->FindClass(className); \
8013c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find class " className); \
8023c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = jclass(env->NewGlobalRef(var));
8033c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
8043c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
8053c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
8063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find method" methodName);
8073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
80869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornint register_android_app_NativeActivity(JNIEnv* env)
80969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
81069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    //LOGD("register_android_app_NativeActivity");
81169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
8123c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    FIND_CLASS(gNativeActivityClassInfo.clazz, kNativeActivityPathName);
81354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
8143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.dispatchUnhandledKeyEvent,
8153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            gNativeActivityClassInfo.clazz,
8163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            "dispatchUnhandledKeyEvent", "(Landroid/view/KeyEvent;)V");
81754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
81854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFlags,
81954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            gNativeActivityClassInfo.clazz,
82054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFlags", "(II)V");
82154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFormat,
82254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            gNativeActivityClassInfo.clazz,
82354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFormat", "(I)V");
824d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.showIme,
825d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            gNativeActivityClassInfo.clazz,
826d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            "showIme", "(I)V");
827d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.hideIme,
828d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            gNativeActivityClassInfo.clazz,
829d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            "hideIme", "(I)V");
83054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
83169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return AndroidRuntime::registerNativeMethods(
83269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        env, kNativeActivityPathName,
83369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        g_methods, NELEM(g_methods));
83469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
83569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
836a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn} // namespace android
837