android_app_NativeActivity.cpp revision 08d5b8fad8d46ccb64db2fdcb4d66972ec87bf48
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;
482c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    jmethodID preDispatchKeyEvent;
4954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    jmethodID setWindowFlags;
5054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    jmethodID setWindowFormat;
51d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    jmethodID showIme;
52d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    jmethodID hideIme;
533c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} gNativeActivityClassInfo;
543c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
5554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
5654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
57289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstruct ActivityWork {
58289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t cmd;
59289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t arg1;
60289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t arg2;
61289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn};
62289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
63289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornenum {
64289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_DEF_KEY = 1,
65289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_SET_WINDOW_FORMAT,
66289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_SET_WINDOW_FLAGS,
67d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    CMD_SHOW_SOFT_INPUT,
68d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    CMD_HIDE_SOFT_INPUT,
69289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn};
70289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
71289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstatic void write_work(int fd, int32_t cmd, int32_t arg1=0, int32_t arg2=0) {
72289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    ActivityWork work;
73289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.cmd = cmd;
74289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.arg1 = arg1;
75289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.arg2 = arg2;
76289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
77d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("write_work: cmd=%d", cmd);
78d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
79289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornrestart:
80289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int res = write(fd, &work, sizeof(work));
81289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0 && errno == EINTR) {
82289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        goto restart;
83289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
84289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
85289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res == sizeof(work)) return;
86289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
87289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0) LOGW("Failed writing to work fd: %s", strerror(errno));
88289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    else LOGW("Truncated writing to work fd: %d", res);
89289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
90289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
91289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstatic bool read_work(int fd, ActivityWork* outWork) {
92289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int res = read(fd, outWork, sizeof(ActivityWork));
93289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    // no need to worry about EINTR, poll loop will just come back again.
94289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res == sizeof(ActivityWork)) return true;
95289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
96289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0) LOGW("Failed reading work fd: %s", strerror(errno));
97289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    else LOGW("Truncated reading work fd: %d", res);
98289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    return false;
99289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
100289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
101289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn// ------------------------------------------------------------------------
102289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
103d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn} // namespace android
104d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
105d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornusing namespace android;
106d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
107d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornAInputQueue::AInputQueue(const sp<InputChannel>& channel, int workWrite) :
1082c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        mWorkWrite(workWrite), mConsumer(channel), mSeq(0) {
109d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int msgpipe[2];
110d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (pipe(msgpipe)) {
111d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        LOGW("could not create pipe: %s", strerror(errno));
112d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mDispatchKeyRead = mDispatchKeyWrite = -1;
113d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    } else {
114d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mDispatchKeyRead = msgpipe[0];
115d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mDispatchKeyWrite = msgpipe[1];
116d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        int result = fcntl(mDispatchKeyRead, F_SETFL, O_NONBLOCK);
117d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make AInputQueue read pipe "
118d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
119d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        result = fcntl(mDispatchKeyWrite, F_SETFL, O_NONBLOCK);
120d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make AInputQueue write pipe "
121d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
1223c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
123d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
124d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
125d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornAInputQueue::~AInputQueue() {
126d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    close(mDispatchKeyRead);
127d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    close(mDispatchKeyWrite);
128d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
129d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
130d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::attachLooper(ALooper* looper, ALooper_callbackFunc* callback, void* data) {
131d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop = static_cast<android::PollLoop*>(looper);
132d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop->setLooperCallback(mConsumer.getChannel()->getReceivePipeFd(),
133d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            POLLIN, callback, data);
134d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop->setLooperCallback(mDispatchKeyRead,
135d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            POLLIN, callback, data);
136d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
137d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
138d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::detachLooper() {
139d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop->removeCallback(mConsumer.getChannel()->getReceivePipeFd());
140d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mPollLoop->removeCallback(mDispatchKeyRead);
141d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
142d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
143d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornint32_t AInputQueue::hasEvents() {
144d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    struct pollfd pfd[2];
145d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
146d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].fd = mConsumer.getChannel()->getReceivePipeFd();
147d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].events = POLLIN;
148d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].revents = 0;
149d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[1].fd = mDispatchKeyRead;
150d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].events = POLLIN;
151d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].revents = 0;
1523c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
153d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int nfd = poll(pfd, 2, 0);
154d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (nfd <= 0) return 0;
155d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return (pfd[0].revents == POLLIN || pfd[1].revents == POLLIN) ? 1 : -1;
156d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
157d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
158d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornint32_t AInputQueue::getEvent(AInputEvent** outEvent) {
159d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    *outEvent = NULL;
160d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
1612c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    bool finishNow = false;
1622c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
163d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    char byteread;
164d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    ssize_t nRead = read(mDispatchKeyRead, &byteread, 1);
165d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (nRead == 1) {
1663c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.lock();
167d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (mDispatchingKeys.size() > 0) {
168d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            KeyEvent* kevent = mDispatchingKeys[0];
169d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            *outEvent = kevent;
170d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            mDispatchingKeys.removeAt(0);
1712c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            in_flight_event inflight;
1722c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            inflight.event = kevent;
1732c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            inflight.seq = -1;
1742c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            inflight.doFinish = false;
1752c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mInFlightEvents.push(inflight);
1762c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        }
1772c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (mFinishPreDispatches.size() > 0) {
1782c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            finish_pre_dispatch finish(mFinishPreDispatches[0]);
1792c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mFinishPreDispatches.removeAt(0);
1802c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            const size_t N = mInFlightEvents.size();
1812c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            for (size_t i=0; i<N; i++) {
1822c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                const in_flight_event& inflight(mInFlightEvents[i]);
1832c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                if (inflight.seq == finish.seq) {
1842c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                    *outEvent = inflight.event;
1852c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                    finishNow = finish.handled;
1862c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                }
1872c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
1882c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (*outEvent == NULL) {
1892c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                LOGW("getEvent couldn't find inflight for seq %d", finish.seq);
1902c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
1913c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1923c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mLock.unlock();
1932c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
1942c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (finishNow) {
1952c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            finishEvent(*outEvent, true);
1962c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            *outEvent = NULL;
1972c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            return -1;
1982c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        } else if (*outEvent != NULL) {
199d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            return 0;
200d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
2013c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
2023c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
203d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int32_t res = mConsumer.receiveDispatchSignal();
204d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (res != android::OK) {
205d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        LOGE("channel '%s' ~ Failed to receive dispatch signal.  status=%d",
206d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                mConsumer.getChannel()->getName().string(), res);
207d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        return -1;
208d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
209d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
210d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    InputEvent* myEvent = NULL;
2112c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    res = mConsumer.consume(this, &myEvent);
212d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (res != android::OK) {
213d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        LOGW("channel '%s' ~ Failed to consume input event.  status=%d",
214d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                mConsumer.getChannel()->getName().string(), res);
215d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mConsumer.sendFinishedSignal();
216d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        return -1;
217d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
218d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
2192c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    in_flight_event inflight;
2202c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    inflight.event = myEvent;
2212c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    inflight.seq = -1;
2222c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    inflight.doFinish = true;
2232c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mInFlightEvents.push(inflight);
2242c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
225d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    *outEvent = myEvent;
226d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return 0;
227d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
228d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
2292c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornbool AInputQueue::preDispatchEvent(AInputEvent* event) {
2302c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (((InputEvent*)event)->getType() != AINPUT_EVENT_TYPE_KEY) {
2312c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        // The IME only cares about key events.
2322c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        return false;
2332c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
2342c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
2352c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    // For now we only send system keys to the IME...  this avoids having
2362c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    // critical keys like DPAD go through this path.  We really need to have
2372c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    // the IME report which keys it wants.
2382c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (!((KeyEvent*)event)->isSystemKey()) {
2392c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        return false;
2402c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
2412c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
2422c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    return preDispatchKey((KeyEvent*)event);
2432c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
2442c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
245d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::finishEvent(AInputEvent* event, bool handled) {
2462c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("finishEvent: %p handled=%d", event, handled ? 1 : 0);
247d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
248c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    if (!handled && ((InputEvent*)event)->getType() == AINPUT_EVENT_TYPE_KEY
249d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            && ((KeyEvent*)event)->hasDefaultAction()) {
250d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        // The app didn't handle this, but it may have a default action
251d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        // associated with it.  We need to hand this back to Java to be
252d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        // executed.
2532c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        doUnhandledKey((KeyEvent*)event);
2542c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        return;
255d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
256d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
2572c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.lock();
2582c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    const size_t N = mInFlightEvents.size();
259d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    for (size_t i=0; i<N; i++) {
2602c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        const in_flight_event& inflight(mInFlightEvents[i]);
2612c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (inflight.event == event) {
2622c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (inflight.doFinish) {
2632c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                int32_t res = mConsumer.sendFinishedSignal();
2642c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                if (res != android::OK) {
2652c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                    LOGW("Failed to send finished signal on channel '%s'.  status=%d",
2662c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                            mConsumer.getChannel()->getName().string(), res);
2672c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                }
2682c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
2692c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (static_cast<InputEvent*>(event)->getType() == AINPUT_EVENT_TYPE_KEY) {
2702c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                mAvailKeyEvents.push(static_cast<KeyEvent*>(event));
2712c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            } else {
2722c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                mAvailMotionEvents.push(static_cast<MotionEvent*>(event));
2732c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
2742c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mInFlightEvents.removeAt(i);
2752c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mLock.unlock();
2762c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            return;
2773c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
2783c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
2792c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.unlock();
2803c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2812c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOGW("finishEvent called for unknown event: %p", event);
282d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
283d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
284d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::dispatchEvent(android::KeyEvent* event) {
285d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.lock();
286d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("dispatchEvent: dispatching=%d write=%d\n", mDispatchingKeys.size(),
287d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            mDispatchKeyWrite);
288d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mDispatchingKeys.add(event);
2892c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    wakeupDispatch();
290d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.unlock();
2912c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
292d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
2932c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornvoid AInputQueue::finishPreDispatch(int seq, bool handled) {
2942c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.lock();
2952c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("finishPreDispatch: seq=%d handled=%d\n", seq, handled ? 1 : 0);
2962c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    finish_pre_dispatch finish;
2972c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    finish.seq = seq;
2982c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    finish.handled = handled;
2992c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mFinishPreDispatches.add(finish);
3002c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    wakeupDispatch();
3012c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.unlock();
302d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
303d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
304d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornKeyEvent* AInputQueue::consumeUnhandledEvent() {
305d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    KeyEvent* event = NULL;
306d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
307d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.lock();
3082c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (mUnhandledKeys.size() > 0) {
3092c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        event = mUnhandledKeys[0];
3102c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        mUnhandledKeys.removeAt(0);
311d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
312d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.unlock();
313d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
314d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("consumeUnhandledEvent: KeyEvent=%p", event);
315d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
316d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return event;
317d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
318d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
3192c6081ce3593712f30dacd990a97209c791d6cedDianne HackbornKeyEvent* AInputQueue::consumePreDispatchingEvent(int* outSeq) {
3202c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    KeyEvent* event = NULL;
3212c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
322d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.lock();
3232c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (mPreDispatchingKeys.size() > 0) {
3242c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        const in_flight_event& inflight(mPreDispatchingKeys[0]);
3252c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        event = static_cast<KeyEvent*>(inflight.event);
3262c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        *outSeq = inflight.seq;
3272c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        mPreDispatchingKeys.removeAt(0);
3282c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
3292c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.unlock();
3302c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3312c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("consumePreDispatchingEvent: KeyEvent=%p", event);
3322c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3332c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    return event;
3342c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
3352c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3362c6081ce3593712f30dacd990a97209c791d6cedDianne HackbornKeyEvent* AInputQueue::createKeyEvent() {
3372c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.lock();
3382c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    KeyEvent* event;
3392c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (mAvailKeyEvents.size() <= 0) {
3402c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        event = new KeyEvent();
3412c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    } else {
3422c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        event = mAvailKeyEvents.top();
3432c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        mAvailKeyEvents.pop();
3442c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
3452c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.unlock();
3462c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    return event;
3472c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
3482c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3492c6081ce3593712f30dacd990a97209c791d6cedDianne HackbornMotionEvent* AInputQueue::createMotionEvent() {
3502c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.lock();
3512c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    MotionEvent* event;
3522c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (mAvailMotionEvents.size() <= 0) {
3532c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        event = new MotionEvent();
3542c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    } else {
3552c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        event = mAvailMotionEvents.top();
3562c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        mAvailMotionEvents.pop();
3572c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
3582c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.unlock();
3592c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    return event;
3602c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
3612c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3622c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornvoid AInputQueue::doUnhandledKey(KeyEvent* keyEvent) {
3632c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.lock();
3642c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("Unhandled key: pending=%d write=%d\n", mUnhandledKeys.size(), mWorkWrite);
3652c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (mUnhandledKeys.size() <= 0 && mWorkWrite >= 0) {
366d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        write_work(mWorkWrite, CMD_DEF_KEY);
367d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
3682c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mUnhandledKeys.add(keyEvent);
369d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mLock.unlock();
370d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
371d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
3722c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornbool AInputQueue::preDispatchKey(KeyEvent* keyEvent) {
3732c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mLock.lock();
3742c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("preDispatch key: pending=%d write=%d\n", mPreDispatchingKeys.size(), mWorkWrite);
3752c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    const size_t N = mInFlightEvents.size();
3762c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    for (size_t i=0; i<N; i++) {
3772c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        in_flight_event& inflight(mInFlightEvents.editItemAt(i));
3782c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (inflight.event == keyEvent) {
3792c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (inflight.seq >= 0) {
3802c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                // This event has already been pre-dispatched!
3812c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                LOG_TRACE("Event already pre-dispatched!");
3822c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                mLock.unlock();
3832c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                return false;
3842c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
3852c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mSeq++;
3862c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (mSeq < 0) mSeq = 1;
3872c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            inflight.seq = mSeq;
3882c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3892c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (mPreDispatchingKeys.size() <= 0 && mWorkWrite >= 0) {
3902c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                write_work(mWorkWrite, CMD_DEF_KEY);
3912c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
3922c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mPreDispatchingKeys.add(inflight);
3932c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mLock.unlock();
3942c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            return true;
3952c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        }
3962c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
3972c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3982c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOGW("preDispatchKey called for unknown event: %p", keyEvent);
3992c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    return false;
4002c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
4012c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
4022c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornvoid AInputQueue::wakeupDispatch() {
4032c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornrestart:
4042c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    char dummy = 0;
4052c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    int res = write(mDispatchKeyWrite, &dummy, sizeof(dummy));
4062c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (res < 0 && errno == EINTR) {
4072c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        goto restart;
4082c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
4092c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
4102c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (res == sizeof(dummy)) return;
4112c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
4122c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (res < 0) LOGW("Failed writing to dispatch fd: %s", strerror(errno));
4132c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    else LOGW("Truncated writing to dispatch fd: %d", res);
4142c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
4152c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
416d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornnamespace android {
4173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
41854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
41954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
42054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
42154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Native state for interacting with the NativeActivity class.
42254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
423289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstruct NativeCode : public ANativeActivity {
4242e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) {
425d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        memset((ANativeActivity*)this, 0, sizeof(ANativeActivity));
426d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        memset(&callbacks, 0, sizeof(callbacks));
42774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        dlhandle = _dlhandle;
42874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        createActivityFunc = _createFunc;
42954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        nativeWindow = NULL;
430a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
431a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
4323c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mainWorkRead = mainWorkWrite = -1;
43374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
43474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
43574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    ~NativeCode() {
436289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (callbacks.onDestroy != NULL) {
437289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            callbacks.onDestroy(this);
438289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        }
439289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (env != NULL && clazz != NULL) {
440289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            env->DeleteGlobalRef(clazz);
4413c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
4423c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pollLoop != NULL && mainWorkRead >= 0) {
4433c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            pollLoop->removeCallback(mainWorkRead);
4443c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
4453c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (nativeInputQueue != NULL) {
4463c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            nativeInputQueue->mWorkWrite = -1;
4473c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
448a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setSurface(NULL);
449a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setInputChannel(NULL);
4503c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkRead >= 0) close(mainWorkRead);
4513c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkWrite >= 0) close(mainWorkWrite);
45274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (dlhandle != NULL) {
45354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // for now don't unload...  we probably should clean this
45454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // up and only keep one open dlhandle per proc, since there
45554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // is really no benefit to unloading the code.
45654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            //dlclose(dlhandle);
45774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
45874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
45974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
46074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    void setSurface(jobject _surface) {
46174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (_surface != NULL) {
462289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            nativeWindow = android_Surface_getNativeWindow(env, _surface);
46374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        } else {
46454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            nativeWindow = NULL;
46574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
46674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
46774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
468a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    status_t setInputChannel(jobject _channel) {
469a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (inputChannel != NULL) {
470a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            delete nativeInputQueue;
471289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            env->DeleteGlobalRef(inputChannel);
472a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
473a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
474a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
475a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (_channel != NULL) {
476289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            inputChannel = env->NewGlobalRef(_channel);
477a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            sp<InputChannel> ic =
478289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    android_view_InputChannel_getInputChannel(env, _channel);
479a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            if (ic != NULL) {
480d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                nativeInputQueue = new AInputQueue(ic, mainWorkWrite);
481a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                if (nativeInputQueue->getConsumer().initialize() != android::OK) {
482a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    delete nativeInputQueue;
483a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    nativeInputQueue = NULL;
484a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    return UNKNOWN_ERROR;
485a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                }
486a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            } else {
487a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                return UNKNOWN_ERROR;
488a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            }
489a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
490a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        return OK;
491a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
492a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
4932e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivityCallbacks callbacks;
49469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
49569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* dlhandle;
4962e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivity_createFunc* createActivityFunc;
49774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
498682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn    String8 internalDataPath;
499682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn    String8 externalDataPath;
500682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
50154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    sp<ANativeWindow> nativeWindow;
502d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int32_t lastWindowWidth;
503d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int32_t lastWindowHeight;
504d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
505a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    jobject inputChannel;
506d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    struct AInputQueue* nativeInputQueue;
5073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
5083c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    // These are used to wake up the main thread to process work.
5093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkRead;
5103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkWrite;
5113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    sp<PollLoop> pollLoop;
51269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
51369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
514289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornvoid android_NativeActivity_setWindowFormat(
515289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        ANativeActivity* activity, int32_t format) {
516289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
517289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FORMAT, format);
518289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
519289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
520289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornvoid android_NativeActivity_setWindowFlags(
521289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        ANativeActivity* activity, int32_t values, int32_t mask) {
522289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
523289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FLAGS, values, mask);
524289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
525289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
526d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid android_NativeActivity_showSoftInput(
527d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        ANativeActivity* activity, int32_t flags) {
528d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
529d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    write_work(code->mainWorkWrite, CMD_SHOW_SOFT_INPUT, flags);
530d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
531d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
532d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid android_NativeActivity_hideSoftInput(
533d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        ANativeActivity* activity, int32_t flags) {
534d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
535d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    write_work(code->mainWorkWrite, CMD_HIDE_SOFT_INPUT, flags);
536d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
537d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
53854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
53954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
54054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
54154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Callback for handling native events on the application's main thread.
54254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
5433c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic bool mainWorkCallback(int fd, int events, void* data) {
5443c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    NativeCode* code = (NativeCode*)data;
545289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if ((events & POLLIN) == 0) {
546289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        return true;
547289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
548289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
549289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    ActivityWork work;
550289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (!read_work(code->mainWorkRead, &work)) {
551289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        return true;
552289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
553d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
554d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("mainWorkCallback: cmd=%d", work.cmd);
555d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
556289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    switch (work.cmd) {
557289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_DEF_KEY: {
558289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            KeyEvent* keyEvent;
559d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            while ((keyEvent=code->nativeInputQueue->consumeUnhandledEvent()) != NULL) {
560289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                jobject inputEventObj = android_view_KeyEvent_fromNative(
561289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                        code->env, keyEvent);
562289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                code->env->CallVoidMethod(code->clazz,
563289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                        gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
5642c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                code->nativeInputQueue->finishEvent(keyEvent, true);
5652c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
5662c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            int seq;
5672c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            while ((keyEvent=code->nativeInputQueue->consumePreDispatchingEvent(&seq)) != NULL) {
5682c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                jobject inputEventObj = android_view_KeyEvent_fromNative(
5692c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                        code->env, keyEvent);
5702c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                code->env->CallVoidMethod(code->clazz,
5712c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                        gNativeActivityClassInfo.preDispatchKeyEvent, inputEventObj, seq);
5723c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            }
573289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
574289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_SET_WINDOW_FORMAT: {
575289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->env->CallVoidMethod(code->clazz,
576289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    gNativeActivityClassInfo.setWindowFormat, work.arg1);
577289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
578289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_SET_WINDOW_FLAGS: {
579289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->env->CallVoidMethod(code->clazz,
580289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    gNativeActivityClassInfo.setWindowFlags, work.arg1, work.arg2);
581289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
582d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        case CMD_SHOW_SOFT_INPUT: {
583d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->env->CallVoidMethod(code->clazz,
584d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    gNativeActivityClassInfo.showIme, work.arg1);
585d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        } break;
586d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        case CMD_HIDE_SOFT_INPUT: {
587d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->env->CallVoidMethod(code->clazz,
588d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    gNativeActivityClassInfo.hideIme, work.arg1);
589d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        } break;
590289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        default:
591289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            LOGW("Unknown work command: %d", work.cmd);
592289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            break;
5933c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
5943c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
5953c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return true;
5963c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
5973c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
59854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
59954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
60069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic jint
601682674154e3fe88f6061245145f934f25f1a2eb8Dianne HackbornloadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jobject messageQueue,
6026cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate        jstring internalDataDir, jstring externalDataDir, int sdkVersion,
60308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        jobject jAssetMgr, jbyteArray savedState)
60469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
605d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("loadNativeCode_native");
606d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
60769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    const char* pathStr = env->GetStringUTFChars(path, NULL);
60869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    NativeCode* code = NULL;
60969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
61069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* handle = dlopen(pathStr, RTLD_LAZY);
61169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
61269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    env->ReleaseStringUTFChars(path, pathStr);
61369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
61469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != NULL) {
6152e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        code = new NativeCode(handle, (ANativeActivity_createFunc*)
6162e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn                dlsym(handle, "ANativeActivity_onCreate"));
61769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->createActivityFunc == NULL) {
6182e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("ANativeActivity_onCreate not found");
61969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            delete code;
62069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            return 0;
62169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
6223c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
6233c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop = android_os_MessageQueue_getPollLoop(env, messageQueue);
6243c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (code->pollLoop == NULL) {
6253c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("Unable to retrieve MessageQueue's PollLoop");
6263c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
6273c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
6283c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
6293c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
6303c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        int msgpipe[2];
6313c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pipe(msgpipe)) {
6323c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            LOGW("could not create pipe: %s", strerror(errno));
6333c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
6343c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
6353c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
6363c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkRead = msgpipe[0];
6373c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkWrite = msgpipe[1];
638d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK);
639d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make main work read pipe "
640d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
641d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
642d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make main work write pipe "
643d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
6443c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->pollLoop->setCallback(code->mainWorkRead, POLLIN, mainWorkCallback, code);
6453c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
646289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->ANativeActivity::callbacks = &code->callbacks;
647289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (env->GetJavaVM(&code->vm) < 0) {
6482e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            LOGW("NativeActivity GetJavaVM failed");
6492e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            delete code;
6502e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            return 0;
6512e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        }
652289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->env = env;
653289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->clazz = env->NewGlobalRef(clazz);
6546cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate
655682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
656682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        code->internalDataPath = dirStr;
657289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->internalDataPath = code->internalDataPath.string();
658682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        env->ReleaseStringUTFChars(path, dirStr);
659682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
660682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        dirStr = env->GetStringUTFChars(externalDataDir, NULL);
661682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        code->externalDataPath = dirStr;
662289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->externalDataPath = code->externalDataPath.string();
663682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        env->ReleaseStringUTFChars(path, dirStr);
6646cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate
665289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->sdkVersion = sdkVersion;
666682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
6676cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate        code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
6686cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate
66908d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        jbyte* rawSavedState = NULL;
67008d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        jsize rawSavedSize = 0;
67108d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        if (savedState != NULL) {
67208d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            rawSavedState = env->GetByteArrayElements(savedState, NULL);
67308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            rawSavedSize = env->GetArrayLength(savedState);
67408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        }
67508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
67608d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        code->createActivityFunc(code, rawSavedState, rawSavedSize);
67708d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
67808d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        if (rawSavedState != NULL) {
67908d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
68008d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        }
68169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
68269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
68369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return (jint)code;
68469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
68569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
68669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
68769969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornunloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle)
68869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
689d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("unloadNativeCode_native");
69069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
69169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
69269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        delete code;
69369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
69469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
69569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
69669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
69769969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStart_native(JNIEnv* env, jobject clazz, jint handle)
69869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
699d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onStart_native");
70069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
70169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
70269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStart != NULL) {
703289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onStart(code);
70469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
70569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
70669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
70769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
70869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
70969969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonResume_native(JNIEnv* env, jobject clazz, jint handle)
71069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
711d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onResume_native");
71269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
71369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
71469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onResume != NULL) {
715289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onResume(code);
71669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
71769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
71869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
71969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
72008d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackbornstatic jbyteArray
72169969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle)
72269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
723d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSaveInstanceState_native");
72408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
72508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    jbyteArray array = NULL;
72608d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
72769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
72869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
72969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onSaveInstanceState != NULL) {
73069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            size_t len = 0;
73108d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            jbyte* state = (jbyte*)code->callbacks.onSaveInstanceState(code, &len);
73208d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            if (len > 0) {
73308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                array = env->NewByteArray(len);
73408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                if (array != NULL) {
73508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                    env->SetByteArrayRegion(array, 0, len, state);
73608d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                }
73708d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            }
73808d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            if (state != NULL) {
73908d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                free(state);
74008d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            }
74169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
74269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
74308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
74408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    return array;
74569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
74669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
74769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
74869969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonPause_native(JNIEnv* env, jobject clazz, jint handle)
74969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
750d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onPause_native");
75169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
75269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
75369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onPause != NULL) {
754289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onPause(code);
75569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
75669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
75769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
75869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
75969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
76069969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStop_native(JNIEnv* env, jobject clazz, jint handle)
76169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
762d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onStop_native");
76369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
76469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
76569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStop != NULL) {
766289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onStop(code);
76769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
76869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
76969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
77069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
77169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
77208d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne HackbornonConfigurationChanged_native(JNIEnv* env, jobject clazz, jint handle)
77308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn{
77408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    LOG_TRACE("onConfigurationChanged_native");
77508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    if (handle != 0) {
77608d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
77708d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        if (code->callbacks.onConfigurationChanged != NULL) {
77808d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            code->callbacks.onConfigurationChanged(code);
77908d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        }
78008d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    }
78108d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn}
78208d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
78308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackbornstatic void
78469969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonLowMemory_native(JNIEnv* env, jobject clazz, jint handle)
78569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
786d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onLowMemory_native");
78769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
78869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
78969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onLowMemory != NULL) {
790289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onLowMemory(code);
79169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
79269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
79369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
79469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
79569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
79669969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean focused)
79769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
798d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onWindowFocusChanged_native");
79969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
80069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
80169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onWindowFocusChanged != NULL) {
802289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onWindowFocusChanged(code, focused ? 1 : 0);
80369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
80469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
80569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
80669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
80774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
80874323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
80974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
810d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceCreated_native");
81174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
81274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
81374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(surface);
81454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
815289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onNativeWindowCreated(code,
81654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
81774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
81874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
81974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
82074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
821d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic int32_t getWindowProp(ANativeWindow* window, int what) {
822d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int value;
823d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int res = window->query(window, what, &value);
824d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return res < 0 ? res : value;
825d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
826d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
82774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
82874323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface,
82974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        jint format, jint width, jint height)
83074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
831d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceChanged_native");
83274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
83374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
83454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        sp<ANativeWindow> oldNativeWindow = code->nativeWindow;
83554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        code->setSurface(surface);
83654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (oldNativeWindow != code->nativeWindow) {
8378ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn            if (oldNativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
838289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                code->callbacks.onNativeWindowDestroyed(code,
8398ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn                        oldNativeWindow.get());
8408ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn            }
841d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            if (code->nativeWindow != NULL) {
842d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                if (code->callbacks.onNativeWindowCreated != NULL) {
843d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    code->callbacks.onNativeWindowCreated(code,
844d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                            code->nativeWindow.get());
845d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                }
846d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                code->lastWindowWidth = getWindowProp(code->nativeWindow.get(),
847d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                        NATIVE_WINDOW_WIDTH);
848d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                code->lastWindowHeight = getWindowProp(code->nativeWindow.get(),
849d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                        NATIVE_WINDOW_HEIGHT);
850d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            }
851d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        } else {
852d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            // Maybe it resized?
853d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            int32_t newWidth = getWindowProp(code->nativeWindow.get(),
854d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    NATIVE_WINDOW_WIDTH);
855d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            int32_t newHeight = getWindowProp(code->nativeWindow.get(),
856d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    NATIVE_WINDOW_HEIGHT);
857d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            if (newWidth != code->lastWindowWidth
858d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    || newHeight != code->lastWindowHeight) {
859d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                if (code->callbacks.onNativeWindowResized != NULL) {
860d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    code->callbacks.onNativeWindowResized(code,
861d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                            code->nativeWindow.get());
862d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                }
86354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            }
86474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
86574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
86674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
86774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
86874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
869d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornonSurfaceRedrawNeeded_native(JNIEnv* env, jobject clazz, jint handle)
870d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn{
871d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceRedrawNeeded_native");
872d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (handle != 0) {
873d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
874d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowRedrawNeeded != NULL) {
875d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->callbacks.onNativeWindowRedrawNeeded(code, code->nativeWindow.get());
876d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
877d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
878d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
879d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
880d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic void
88174323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
88274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
883d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceDestroyed_native");
88474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
88574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
88654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
887289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onNativeWindowDestroyed(code,
88854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
88974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
89074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(NULL);
89174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
89274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
89374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
894a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
895a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
896a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
897d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onInputChannelCreated_native");
898a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
899a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
900a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        status_t err = code->setInputChannel(channel);
901a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (err != OK) {
902a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            jniThrowException(env, "java/lang/IllegalStateException",
903a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    "Error setting input channel");
904a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            return;
905a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
906a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->callbacks.onInputQueueCreated != NULL) {
907289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onInputQueueCreated(code,
908a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
909a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
910a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
911a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
912a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
913a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
914a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
915a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
916d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onInputChannelDestroyed_native");
917a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
918a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
919a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->nativeInputQueue != NULL
920a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                && code->callbacks.onInputQueueDestroyed != NULL) {
921289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onInputQueueDestroyed(code,
922a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
923a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
924a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        code->setInputChannel(NULL);
925a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
926a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
927a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
928d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic void
929d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornonContentRectChanged_native(JNIEnv* env, jobject clazz, jint handle,
930d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        jint x, jint y, jint w, jint h)
931d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn{
932d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onContentRectChanged_native");
933d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (handle != 0) {
934d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
935d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (code->callbacks.onContentRectChanged != NULL) {
936d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            ARect rect;
937d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.left = x;
938d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.top = y;
939d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.right = x+w;
940d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.bottom = y+h;
941d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->callbacks.onContentRectChanged(code, &rect);
942d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
943d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
944d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
945d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
946d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic void
947d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackborndispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle, jobject eventObj)
948d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn{
949d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("dispatchKeyEvent_native");
950d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (handle != 0) {
951d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
952d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (code->nativeInputQueue != NULL) {
9532c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            KeyEvent* event = code->nativeInputQueue->createKeyEvent();
954c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            android_view_KeyEvent_toNative(env, eventObj, event);
955d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->nativeInputQueue->dispatchEvent(event);
956d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
957d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
958d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
959d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
9602c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornstatic void
9612c6081ce3593712f30dacd990a97209c791d6cedDianne HackbornfinishPreDispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle,
9622c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        jint seq, jboolean handled)
9632c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn{
9642c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("finishPreDispatchKeyEvent_native");
9652c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (handle != 0) {
9662c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        NativeCode* code = (NativeCode*)handle;
9672c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (code->nativeInputQueue != NULL) {
9682c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            code->nativeInputQueue->finishPreDispatch(seq, handled ? true : false);
9692c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        }
9702c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
9712c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
9722c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
97369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const JNINativeMethod g_methods[] = {
97408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    { "loadNativeCode", "(Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)I",
975682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn            (void*)loadNativeCode_native },
97669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
97769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStartNative", "(I)V", (void*)onStart_native },
97869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onResumeNative", "(I)V", (void*)onResume_native },
97908d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    { "onSaveInstanceStateNative", "(I)[B", (void*)onSaveInstanceState_native },
98069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onPauseNative", "(I)V", (void*)onPause_native },
98169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStopNative", "(I)V", (void*)onStop_native },
98208d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    { "onConfigurationChangedNative", "(I)V", (void*)onConfigurationChanged_native },
98369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native },
98469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native },
98554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceCreatedNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceCreated_native },
98654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceChangedNative", "(ILandroid/view/Surface;III)V", (void*)onSurfaceChanged_native },
987d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    { "onSurfaceRedrawNeededNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceRedrawNeeded_native },
98854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceDestroyedNative", "(I)V", (void*)onSurfaceDestroyed_native },
989a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelCreatedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelCreated_native },
990a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelDestroyedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelDestroyed_native },
991d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    { "onContentRectChangedNative", "(IIIII)V", (void*)onContentRectChanged_native },
992d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    { "dispatchKeyEventNative", "(ILandroid/view/KeyEvent;)V", (void*)dispatchKeyEvent_native },
9932c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    { "finishPreDispatchKeyEventNative", "(IIZ)V", (void*)finishPreDispatchKeyEvent_native },
99469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
99569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
99669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const char* const kNativeActivityPathName = "android/app/NativeActivity";
99769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
9983c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define FIND_CLASS(var, className) \
9993c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->FindClass(className); \
10003c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find class " className); \
10013c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = jclass(env->NewGlobalRef(var));
10023c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
10033c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
10043c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
10053c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find method" methodName);
10063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
100769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornint register_android_app_NativeActivity(JNIEnv* env)
100869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
100969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    //LOGD("register_android_app_NativeActivity");
101069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
10113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    FIND_CLASS(gNativeActivityClassInfo.clazz, kNativeActivityPathName);
101254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
10133c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.dispatchUnhandledKeyEvent,
10143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            gNativeActivityClassInfo.clazz,
10153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            "dispatchUnhandledKeyEvent", "(Landroid/view/KeyEvent;)V");
10162c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.preDispatchKeyEvent,
10172c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            gNativeActivityClassInfo.clazz,
10182c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            "preDispatchKeyEvent", "(Landroid/view/KeyEvent;I)V");
101954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
102054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFlags,
102154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            gNativeActivityClassInfo.clazz,
102254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFlags", "(II)V");
102354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFormat,
102454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            gNativeActivityClassInfo.clazz,
102554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFormat", "(I)V");
1026d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.showIme,
1027d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            gNativeActivityClassInfo.clazz,
1028d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            "showIme", "(I)V");
1029d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.hideIme,
1030d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            gNativeActivityClassInfo.clazz,
1031d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            "hideIme", "(I)V");
103254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
103369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return AndroidRuntime::registerNativeMethods(
103469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        env, kNativeActivityPathName,
103569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        g_methods, NELEM(g_methods));
103669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
103769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
1038a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn} // namespace android
1039