android_app_NativeActivity.cpp revision 64a55af0ac700baecb0877235eb42caac59a3560
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
24289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn#include <android_runtime/android_app_NativeActivity.h>
256cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate#include <android_runtime/android_util_AssetManager.h>
268335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <android_runtime/android_view_Surface.h>
278335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <android_runtime/AndroidRuntime.h>
28b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian#include <androidfw/InputTransport.h>
298335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian
308335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <gui/Surface.h>
318335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian
328335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <system/window.h>
338335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian
344fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#include <utils/Looper.h>
3569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
363c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "JNIHelp.h"
373c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_os_MessageQueue.h"
383c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_InputChannel.h"
393c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#include "android_view_KeyEvent.h"
4069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
41db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn#define LOG_TRACE(...)
4228d9f024e043817212b15f04128d0464330502eaSteve Block//#define LOG_TRACE(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
43d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
4469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornnamespace android
4569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
4669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
473c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic struct {
483c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    jmethodID dispatchUnhandledKeyEvent;
492c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    jmethodID preDispatchKeyEvent;
50db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn    jmethodID finish;
5154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    jmethodID setWindowFlags;
5254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    jmethodID setWindowFormat;
53d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    jmethodID showIme;
54d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    jmethodID hideIme;
553c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} gNativeActivityClassInfo;
563c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
5754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
5854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
59289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstruct ActivityWork {
60289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t cmd;
61289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t arg1;
62289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int32_t arg2;
63289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn};
64289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
65289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornenum {
66289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_DEF_KEY = 1,
67db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn    CMD_FINISH,
68289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_SET_WINDOW_FORMAT,
69289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    CMD_SET_WINDOW_FLAGS,
70d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    CMD_SHOW_SOFT_INPUT,
71d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    CMD_HIDE_SOFT_INPUT,
72289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn};
73289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
74289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstatic void write_work(int fd, int32_t cmd, int32_t arg1=0, int32_t arg2=0) {
75289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    ActivityWork work;
76289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.cmd = cmd;
77289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.arg1 = arg1;
78289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    work.arg2 = arg2;
79289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
80d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("write_work: cmd=%d", cmd);
81d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
82289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornrestart:
83289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int res = write(fd, &work, sizeof(work));
84289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res < 0 && errno == EINTR) {
85289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        goto restart;
86289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
87289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
88289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res == sizeof(work)) return;
89289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
908564c8da817a845353d213acd8636b76f567b234Steve Block    if (res < 0) ALOGW("Failed writing to work fd: %s", strerror(errno));
918564c8da817a845353d213acd8636b76f567b234Steve Block    else ALOGW("Truncated writing to work fd: %d", res);
92289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
93289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
94289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstatic bool read_work(int fd, ActivityWork* outWork) {
95289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    int res = read(fd, outWork, sizeof(ActivityWork));
96289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    // no need to worry about EINTR, poll loop will just come back again.
97289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (res == sizeof(ActivityWork)) return true;
98289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
998564c8da817a845353d213acd8636b76f567b234Steve Block    if (res < 0) ALOGW("Failed reading work fd: %s", strerror(errno));
1008564c8da817a845353d213acd8636b76f567b234Steve Block    else ALOGW("Truncated reading work fd: %d", res);
101289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    return false;
102289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
103289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
104289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn// ------------------------------------------------------------------------
105289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
106d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn} // namespace android
107d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
108d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornusing namespace android;
109d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
110d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornAInputQueue::AInputQueue(const sp<InputChannel>& channel, int workWrite) :
1112c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        mWorkWrite(workWrite), mConsumer(channel), mSeq(0) {
112d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int msgpipe[2];
113d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (pipe(msgpipe)) {
1148564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("could not create pipe: %s", strerror(errno));
115d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mDispatchKeyRead = mDispatchKeyWrite = -1;
116d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    } else {
117d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mDispatchKeyRead = msgpipe[0];
118d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        mDispatchKeyWrite = msgpipe[1];
119d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        int result = fcntl(mDispatchKeyRead, F_SETFL, O_NONBLOCK);
120d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make AInputQueue read pipe "
121d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
122d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        result = fcntl(mDispatchKeyWrite, F_SETFL, O_NONBLOCK);
123d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make AInputQueue write pipe "
124d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
1253c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
126d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
127d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
128d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornAInputQueue::~AInputQueue() {
129d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    close(mDispatchKeyRead);
130d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    close(mDispatchKeyWrite);
131d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
132d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
13342c03e579aade011b451e2a13ea3f44a2ef0056aDianne Hackbornvoid AInputQueue::attachLooper(ALooper* looper, int ident,
1344fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown        ALooper_callbackFunc callback, void* data) {
1354fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    mLooper = static_cast<android::Looper*>(looper);
136cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    mLooper->addFd(mConsumer.getChannel()->getFd(),
1374fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown            ident, ALOOPER_EVENT_INPUT, callback, data);
1384fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    mLooper->addFd(mDispatchKeyRead,
1394fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown            ident, ALOOPER_EVENT_INPUT, callback, data);
140d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
141d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
142d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::detachLooper() {
143cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    mLooper->removeFd(mConsumer.getChannel()->getFd());
1444fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    mLooper->removeFd(mDispatchKeyRead);
145d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
146d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
147d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornint32_t AInputQueue::hasEvents() {
148d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    struct pollfd pfd[2];
149d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
150cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    pfd[0].fd = mConsumer.getChannel()->getFd();
151d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].events = POLLIN;
152d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[0].revents = 0;
153d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    pfd[1].fd = mDispatchKeyRead;
1542bb10f4299f93f809bddb7683f6ba93277da6f28Kenny Root    pfd[1].events = POLLIN;
1552bb10f4299f93f809bddb7683f6ba93277da6f28Kenny Root    pfd[1].revents = 0;
1563c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
157d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int nfd = poll(pfd, 2, 0);
158d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (nfd <= 0) return 0;
1592bb10f4299f93f809bddb7683f6ba93277da6f28Kenny Root    return ((pfd[0].revents & POLLIN) || (pfd[1].revents & POLLIN)) ? 1 : -1;
160d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
161d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
162d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornint32_t AInputQueue::getEvent(AInputEvent** outEvent) {
163d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    *outEvent = NULL;
164d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
165d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    char byteread;
166d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    ssize_t nRead = read(mDispatchKeyRead, &byteread, 1);
1672b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
1682b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    Mutex::Autolock _l(mLock);
1692b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
170d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (nRead == 1) {
171d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (mDispatchingKeys.size() > 0) {
172d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            KeyEvent* kevent = mDispatchingKeys[0];
173d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            *outEvent = kevent;
174d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            mDispatchingKeys.removeAt(0);
1752c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            in_flight_event inflight;
1762c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            inflight.event = kevent;
1772c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            inflight.seq = -1;
178072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            inflight.finishSeq = 0;
1792c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mInFlightEvents.push(inflight);
1802c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        }
1812b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
1822b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown        bool finishNow = false;
1832c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (mFinishPreDispatches.size() > 0) {
1842c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            finish_pre_dispatch finish(mFinishPreDispatches[0]);
1852c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mFinishPreDispatches.removeAt(0);
1862c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            const size_t N = mInFlightEvents.size();
1872c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            for (size_t i=0; i<N; i++) {
1882c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                const in_flight_event& inflight(mInFlightEvents[i]);
1892c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                if (inflight.seq == finish.seq) {
1902c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                    *outEvent = inflight.event;
1912c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                    finishNow = finish.handled;
1922c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                }
1932c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
1942c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (*outEvent == NULL) {
1958564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("getEvent couldn't find inflight for seq %d", finish.seq);
1962c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
1973c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
1982c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
1992c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (finishNow) {
2003915bb845b032dc184dba5e60970b803390ca3edJeff Brown            finishEvent(*outEvent, true, false);
2012c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            *outEvent = NULL;
2022c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            return -1;
2032c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        } else if (*outEvent != NULL) {
204d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            return 0;
205d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
2063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
207d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
208072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    uint32_t consumerSeq;
209d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    InputEvent* myEvent = NULL;
210771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    status_t res = mConsumer.consume(&mPooledInputEventFactory, true /*consumeBatches*/, -1,
2112b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown            &consumerSeq, &myEvent);
212d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (res != android::OK) {
213072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        if (res != android::WOULD_BLOCK) {
214072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            ALOGW("channel '%s' ~ Failed to consume input event.  status=%d",
215072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                    mConsumer.getChannel()->getName().string(), res);
216072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        }
217d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        return -1;
218d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
219d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
2202b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    if (mConsumer.hasDeferredEvent()) {
2212b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown        wakeupDispatchLocked();
2222b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    }
2232b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
2242c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    in_flight_event inflight;
2252c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    inflight.event = myEvent;
2262c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    inflight.seq = -1;
227072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    inflight.finishSeq = consumerSeq;
2282c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mInFlightEvents.push(inflight);
2292c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
230d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    *outEvent = myEvent;
231d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return 0;
232d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
233d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
2342c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornbool AInputQueue::preDispatchEvent(AInputEvent* event) {
2352c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (((InputEvent*)event)->getType() != AINPUT_EVENT_TYPE_KEY) {
2362c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        // The IME only cares about key events.
2372c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        return false;
2382c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
2392c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
2402c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    // For now we only send system keys to the IME...  this avoids having
2412c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    // critical keys like DPAD go through this path.  We really need to have
2422c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    // the IME report which keys it wants.
2432c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (!((KeyEvent*)event)->isSystemKey()) {
2442c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        return false;
2452c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
2462c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
2472c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    return preDispatchKey((KeyEvent*)event);
2482c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
2492c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
2503915bb845b032dc184dba5e60970b803390ca3edJeff Brownvoid AInputQueue::finishEvent(AInputEvent* event, bool handled, bool didDefaultHandling) {
2513915bb845b032dc184dba5e60970b803390ca3edJeff Brown    LOG_TRACE("finishEvent: %p handled=%d, didDefaultHandling=%d", event,
2523915bb845b032dc184dba5e60970b803390ca3edJeff Brown            handled ? 1 : 0, didDefaultHandling ? 1 : 0);
253d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
2543915bb845b032dc184dba5e60970b803390ca3edJeff Brown    if (!handled && !didDefaultHandling
2553915bb845b032dc184dba5e60970b803390ca3edJeff Brown            && ((InputEvent*)event)->getType() == AINPUT_EVENT_TYPE_KEY
256d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            && ((KeyEvent*)event)->hasDefaultAction()) {
257d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        // The app didn't handle this, but it may have a default action
258d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        // associated with it.  We need to hand this back to Java to be
259d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        // executed.
2602c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        doUnhandledKey((KeyEvent*)event);
2612c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        return;
262d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
263d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
2642b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    Mutex::Autolock _l(mLock);
2652b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
2662c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    const size_t N = mInFlightEvents.size();
267d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    for (size_t i=0; i<N; i++) {
2682c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        const in_flight_event& inflight(mInFlightEvents[i]);
2692c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (inflight.event == event) {
270072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            if (inflight.finishSeq) {
271072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                status_t res = mConsumer.sendFinishedSignal(inflight.finishSeq, handled);
2722c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                if (res != android::OK) {
2738564c8da817a845353d213acd8636b76f567b234Steve Block                    ALOGW("Failed to send finished signal on channel '%s'.  status=%d",
2742c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                            mConsumer.getChannel()->getName().string(), res);
2752c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                }
2762c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
2772b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown            mPooledInputEventFactory.recycle(static_cast<InputEvent*>(event));
2782c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mInFlightEvents.removeAt(i);
2792c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            return;
2803c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
2813c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
2822b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
2838564c8da817a845353d213acd8636b76f567b234Steve Block    ALOGW("finishEvent called for unknown event: %p", event);
284d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
285d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
286d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid AInputQueue::dispatchEvent(android::KeyEvent* event) {
2872b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    Mutex::Autolock _l(mLock);
2882b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
289d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("dispatchEvent: dispatching=%d write=%d\n", mDispatchingKeys.size(),
290d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            mDispatchKeyWrite);
291d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    mDispatchingKeys.add(event);
2922b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    wakeupDispatchLocked();
2932c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
294d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
2952c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornvoid AInputQueue::finishPreDispatch(int seq, bool handled) {
2962b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    Mutex::Autolock _l(mLock);
2972b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
2982c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("finishPreDispatch: seq=%d handled=%d\n", seq, handled ? 1 : 0);
2992c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    finish_pre_dispatch finish;
3002c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    finish.seq = seq;
3012c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    finish.handled = handled;
3022c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mFinishPreDispatches.add(finish);
3032b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    wakeupDispatchLocked();
304d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
305d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
306d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornKeyEvent* AInputQueue::consumeUnhandledEvent() {
3072b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    Mutex::Autolock _l(mLock);
308d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
3092b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    KeyEvent* event = NULL;
3102c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (mUnhandledKeys.size() > 0) {
3112c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        event = mUnhandledKeys[0];
3122c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        mUnhandledKeys.removeAt(0);
313d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
314d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
315d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("consumeUnhandledEvent: KeyEvent=%p", event);
316d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return event;
317d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
318d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
3192c6081ce3593712f30dacd990a97209c791d6cedDianne HackbornKeyEvent* AInputQueue::consumePreDispatchingEvent(int* outSeq) {
3202b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    Mutex::Autolock _l(mLock);
3212c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3222b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    KeyEvent* event = NULL;
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
3302c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("consumePreDispatchingEvent: KeyEvent=%p", event);
3312c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    return event;
3322c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
3332c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3342c6081ce3593712f30dacd990a97209c791d6cedDianne HackbornKeyEvent* AInputQueue::createKeyEvent() {
3352b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    Mutex::Autolock _l(mLock);
3362c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3372b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    return mPooledInputEventFactory.createKeyEvent();
3382c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
3392c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3402c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornvoid AInputQueue::doUnhandledKey(KeyEvent* keyEvent) {
3412b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    Mutex::Autolock _l(mLock);
3422b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
3432c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("Unhandled key: pending=%d write=%d\n", mUnhandledKeys.size(), mWorkWrite);
3442c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (mUnhandledKeys.size() <= 0 && mWorkWrite >= 0) {
345d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        write_work(mWorkWrite, CMD_DEF_KEY);
346d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
3472c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mUnhandledKeys.add(keyEvent);
348d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
349d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
3502c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornbool AInputQueue::preDispatchKey(KeyEvent* keyEvent) {
3512b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    Mutex::Autolock _l(mLock);
3522b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
3532c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("preDispatch key: pending=%d write=%d\n", mPreDispatchingKeys.size(), mWorkWrite);
3542c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    const size_t N = mInFlightEvents.size();
3552c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    for (size_t i=0; i<N; i++) {
3562c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        in_flight_event& inflight(mInFlightEvents.editItemAt(i));
3572c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (inflight.event == keyEvent) {
3582c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (inflight.seq >= 0) {
3592c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                // This event has already been pre-dispatched!
3602c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                LOG_TRACE("Event already pre-dispatched!");
3612c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                return false;
3622c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
3632c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mSeq++;
3642c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (mSeq < 0) mSeq = 1;
3652c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            inflight.seq = mSeq;
3662c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3672c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            if (mPreDispatchingKeys.size() <= 0 && mWorkWrite >= 0) {
3682c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                write_work(mWorkWrite, CMD_DEF_KEY);
3692c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
3702c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            mPreDispatchingKeys.add(inflight);
3712c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            return true;
3722c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        }
3732c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
3742c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3758564c8da817a845353d213acd8636b76f567b234Steve Block    ALOGW("preDispatchKey called for unknown event: %p", keyEvent);
3762c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    return false;
3772c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
3782c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3792b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brownvoid AInputQueue::wakeupDispatchLocked() {
3802c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornrestart:
3812c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    char dummy = 0;
3822c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    int res = write(mDispatchKeyWrite, &dummy, sizeof(dummy));
3832c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (res < 0 && errno == EINTR) {
3842c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        goto restart;
3852c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
3862c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3872c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (res == sizeof(dummy)) return;
3882c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
3898564c8da817a845353d213acd8636b76f567b234Steve Block    if (res < 0) ALOGW("Failed writing to dispatch fd: %s", strerror(errno));
3908564c8da817a845353d213acd8636b76f567b234Steve Block    else ALOGW("Truncated writing to dispatch fd: %d", res);
3912c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
3922c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
393d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornnamespace android {
3943c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
39554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
39654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
39754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
39854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Native state for interacting with the NativeActivity class.
39954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
400289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornstruct NativeCode : public ANativeActivity {
4012e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    NativeCode(void* _dlhandle, ANativeActivity_createFunc* _createFunc) {
402d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        memset((ANativeActivity*)this, 0, sizeof(ANativeActivity));
403d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        memset(&callbacks, 0, sizeof(callbacks));
40474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        dlhandle = _dlhandle;
40574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        createActivityFunc = _createFunc;
40654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        nativeWindow = NULL;
407a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
408a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
4093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        mainWorkRead = mainWorkWrite = -1;
41074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
41174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
41274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    ~NativeCode() {
413289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (callbacks.onDestroy != NULL) {
414289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            callbacks.onDestroy(this);
415289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        }
416289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (env != NULL && clazz != NULL) {
417289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            env->DeleteGlobalRef(clazz);
4183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
419603b44589682db3ff33ade172facb0c5e309f1beJeff Brown        if (messageQueue != NULL && mainWorkRead >= 0) {
420603b44589682db3ff33ade172facb0c5e309f1beJeff Brown            messageQueue->getLooper()->removeFd(mainWorkRead);
4213c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
4223c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (nativeInputQueue != NULL) {
4233c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            nativeInputQueue->mWorkWrite = -1;
4243c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
425a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setSurface(NULL);
426a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        setInputChannel(NULL);
4273c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkRead >= 0) close(mainWorkRead);
4283c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (mainWorkWrite >= 0) close(mainWorkWrite);
42974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (dlhandle != NULL) {
43054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // for now don't unload...  we probably should clean this
43154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // up and only keep one open dlhandle per proc, since there
43254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            // is really no benefit to unloading the code.
43354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            //dlclose(dlhandle);
43474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
43574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
43674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
43774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    void setSurface(jobject _surface) {
43874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        if (_surface != NULL) {
43964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            nativeWindow = android_view_Surface_getNativeWindow(env, _surface);
44074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        } else {
44154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            nativeWindow = NULL;
44274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
44374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
44474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
445a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    status_t setInputChannel(jobject _channel) {
446a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (inputChannel != NULL) {
447a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            delete nativeInputQueue;
448289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            env->DeleteGlobalRef(inputChannel);
449a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
450a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        inputChannel = NULL;
451a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        nativeInputQueue = NULL;
452a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (_channel != NULL) {
453289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            inputChannel = env->NewGlobalRef(_channel);
454a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            sp<InputChannel> ic =
455289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    android_view_InputChannel_getInputChannel(env, _channel);
456a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            if (ic != NULL) {
457d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                nativeInputQueue = new AInputQueue(ic, mainWorkWrite);
458a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            } else {
459a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                return UNKNOWN_ERROR;
460a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            }
461a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
462a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        return OK;
463a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
464a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
4652e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivityCallbacks callbacks;
46669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
46769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* dlhandle;
4682e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn    ANativeActivity_createFunc* createActivityFunc;
46974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
470805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn    String8 internalDataPathObj;
471805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn    String8 externalDataPathObj;
472805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn    String8 obbPathObj;
473682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
47454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    sp<ANativeWindow> nativeWindow;
475d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int32_t lastWindowWidth;
476d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int32_t lastWindowHeight;
477d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
478a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    jobject inputChannel;
479d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    struct AInputQueue* nativeInputQueue;
4803c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
4813c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    // These are used to wake up the main thread to process work.
4823c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkRead;
4833c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    int mainWorkWrite;
484603b44589682db3ff33ade172facb0c5e309f1beJeff Brown    sp<MessageQueue> messageQueue;
48569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
48669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
487db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackbornvoid android_NativeActivity_finish(ANativeActivity* activity) {
488db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
489db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn    write_work(code->mainWorkWrite, CMD_FINISH, 0);
490db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn}
491db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn
492289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornvoid android_NativeActivity_setWindowFormat(
493289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        ANativeActivity* activity, int32_t format) {
494289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
495289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FORMAT, format);
496289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
497289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
498289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackbornvoid android_NativeActivity_setWindowFlags(
499289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        ANativeActivity* activity, int32_t values, int32_t mask) {
500289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
501289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    write_work(code->mainWorkWrite, CMD_SET_WINDOW_FLAGS, values, mask);
502289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn}
503289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
504d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid android_NativeActivity_showSoftInput(
505d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        ANativeActivity* activity, int32_t flags) {
506d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
507d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    write_work(code->mainWorkWrite, CMD_SHOW_SOFT_INPUT, flags);
508d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
509d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
510d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornvoid android_NativeActivity_hideSoftInput(
511d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        ANativeActivity* activity, int32_t flags) {
512d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    NativeCode* code = static_cast<NativeCode*>(activity);
513d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    write_work(code->mainWorkWrite, CMD_HIDE_SOFT_INPUT, flags);
514d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
515d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
51654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
51754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
51854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn/*
51954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn * Callback for handling native events on the application's main thread.
52054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn */
5214fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownstatic int mainWorkCallback(int fd, int events, void* data) {
5223c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    NativeCode* code = (NativeCode*)data;
523289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if ((events & POLLIN) == 0) {
5244fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown        return 1;
525289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
526289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
527289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    ActivityWork work;
528289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    if (!read_work(code->mainWorkRead, &work)) {
5294fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown        return 1;
530289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    }
531d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
532d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("mainWorkCallback: cmd=%d", work.cmd);
533d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
534289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn    switch (work.cmd) {
535289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_DEF_KEY: {
536289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            KeyEvent* keyEvent;
537d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            while ((keyEvent=code->nativeInputQueue->consumeUnhandledEvent()) != NULL) {
538289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                jobject inputEventObj = android_view_KeyEvent_fromNative(
539289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                        code->env, keyEvent);
5401f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                jboolean handled;
5411f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                if (inputEventObj) {
5421f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                    handled = code->env->CallBooleanMethod(code->clazz,
5431f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                            gNativeActivityClassInfo.dispatchUnhandledKeyEvent, inputEventObj);
544603b44589682db3ff33ade172facb0c5e309f1beJeff Brown                    code->messageQueue->raiseAndClearException(
545603b44589682db3ff33ade172facb0c5e309f1beJeff Brown                            code->env, "dispatchUnhandledKeyEvent");
5461f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                    code->env->DeleteLocalRef(inputEventObj);
5471f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                } else {
5483762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                    ALOGE("Failed to obtain key event for dispatchUnhandledKeyEvent.");
5491f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                    handled = false;
5501f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                }
5513915bb845b032dc184dba5e60970b803390ca3edJeff Brown                code->nativeInputQueue->finishEvent(keyEvent, handled, true);
5522c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            }
5532c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            int seq;
5542c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            while ((keyEvent=code->nativeInputQueue->consumePreDispatchingEvent(&seq)) != NULL) {
5552c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                jobject inputEventObj = android_view_KeyEvent_fromNative(
5562c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn                        code->env, keyEvent);
5571f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                if (inputEventObj) {
5581f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                    code->env->CallVoidMethod(code->clazz,
5591f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                            gNativeActivityClassInfo.preDispatchKeyEvent, inputEventObj, seq);
560603b44589682db3ff33ade172facb0c5e309f1beJeff Brown                    code->messageQueue->raiseAndClearException(code->env, "preDispatchKeyEvent");
5611f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                    code->env->DeleteLocalRef(inputEventObj);
5621f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                } else {
5633762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                    ALOGE("Failed to obtain key event for preDispatchKeyEvent.");
5641f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                }
5653c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            }
566289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
567db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn        case CMD_FINISH: {
568db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn            code->env->CallVoidMethod(code->clazz, gNativeActivityClassInfo.finish);
569603b44589682db3ff33ade172facb0c5e309f1beJeff Brown            code->messageQueue->raiseAndClearException(code->env, "finish");
570db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn        } break;
571289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_SET_WINDOW_FORMAT: {
572289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->env->CallVoidMethod(code->clazz,
573289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    gNativeActivityClassInfo.setWindowFormat, work.arg1);
574603b44589682db3ff33ade172facb0c5e309f1beJeff Brown            code->messageQueue->raiseAndClearException(code->env, "setWindowFormat");
575289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
576289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        case CMD_SET_WINDOW_FLAGS: {
577289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->env->CallVoidMethod(code->clazz,
578289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                    gNativeActivityClassInfo.setWindowFlags, work.arg1, work.arg2);
579603b44589682db3ff33ade172facb0c5e309f1beJeff Brown            code->messageQueue->raiseAndClearException(code->env, "setWindowFlags");
580289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        } break;
581d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        case CMD_SHOW_SOFT_INPUT: {
582d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->env->CallVoidMethod(code->clazz,
583d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    gNativeActivityClassInfo.showIme, work.arg1);
584603b44589682db3ff33ade172facb0c5e309f1beJeff Brown            code->messageQueue->raiseAndClearException(code->env, "showIme");
585d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        } break;
586d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        case CMD_HIDE_SOFT_INPUT: {
587d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->env->CallVoidMethod(code->clazz,
588d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    gNativeActivityClassInfo.hideIme, work.arg1);
589603b44589682db3ff33ade172facb0c5e309f1beJeff Brown            code->messageQueue->raiseAndClearException(code->env, "hideIme");
590d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        } break;
591289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        default:
5928564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Unknown work command: %d", work.cmd);
593289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            break;
5943c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
5953c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
5964fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    return 1;
5973c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
5983c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
59954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn// ------------------------------------------------------------------------
60054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
60169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic jint
602e21d91c694e828e6285cc50e79b2a6be6e8c692bDianne HackbornloadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName,
603805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        jobject messageQueue, jstring internalDataDir, jstring obbDir,
604805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        jstring externalDataDir, int sdkVersion,
60508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        jobject jAssetMgr, jbyteArray savedState)
60669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
607d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("loadNativeCode_native");
608d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
60969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    const char* pathStr = env->GetStringUTFChars(path, NULL);
61069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    NativeCode* code = NULL;
61169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
61269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    void* handle = dlopen(pathStr, RTLD_LAZY);
61369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
61469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    env->ReleaseStringUTFChars(path, pathStr);
61569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
61669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != NULL) {
617e21d91c694e828e6285cc50e79b2a6be6e8c692bDianne Hackborn        const char* funcStr = env->GetStringUTFChars(funcName, NULL);
6182e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        code = new NativeCode(handle, (ANativeActivity_createFunc*)
619e21d91c694e828e6285cc50e79b2a6be6e8c692bDianne Hackborn                dlsym(handle, funcStr));
620e21d91c694e828e6285cc50e79b2a6be6e8c692bDianne Hackborn        env->ReleaseStringUTFChars(funcName, funcStr);
621e21d91c694e828e6285cc50e79b2a6be6e8c692bDianne Hackborn
62269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->createActivityFunc == NULL) {
6238564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("ANativeActivity_onCreate not found");
62469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            delete code;
62569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            return 0;
62669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
6273c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
628603b44589682db3ff33ade172facb0c5e309f1beJeff Brown        code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
629603b44589682db3ff33ade172facb0c5e309f1beJeff Brown        if (code->messageQueue == NULL) {
630603b44589682db3ff33ade172facb0c5e309f1beJeff Brown            ALOGW("Unable to retrieve native MessageQueue");
6313c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
6323c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
6333c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
6343c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
6353c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        int msgpipe[2];
6363c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        if (pipe(msgpipe)) {
6378564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("could not create pipe: %s", strerror(errno));
6383c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            delete code;
6393c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return 0;
6403c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        }
6413c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkRead = msgpipe[0];
6423c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        code->mainWorkWrite = msgpipe[1];
643d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK);
644d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make main work read pipe "
645d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
646d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
647d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        SLOGW_IF(result != 0, "Could not make main work write pipe "
648d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                "non-blocking: %s", strerror(errno));
649603b44589682db3ff33ade172facb0c5e309f1beJeff Brown        code->messageQueue->getLooper()->addFd(
650603b44589682db3ff33ade172facb0c5e309f1beJeff Brown                code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code);
6513c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
652289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->ANativeActivity::callbacks = &code->callbacks;
653289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        if (env->GetJavaVM(&code->vm) < 0) {
6548564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("NativeActivity GetJavaVM failed");
6552e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            delete code;
6562e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn            return 0;
6572e9f93e8db509d5236229dc8540e0904c5dbb9f5Dianne Hackborn        }
658289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->env = env;
659289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->clazz = env->NewGlobalRef(clazz);
6606cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate
661682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
662805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        code->internalDataPathObj = dirStr;
663805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        code->internalDataPath = code->internalDataPathObj.string();
664805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        env->ReleaseStringUTFChars(internalDataDir, dirStr);
665682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
666682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn        dirStr = env->GetStringUTFChars(externalDataDir, NULL);
667805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        code->externalDataPathObj = dirStr;
668805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        code->externalDataPath = code->externalDataPathObj.string();
669805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        env->ReleaseStringUTFChars(externalDataDir, dirStr);
6706cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate
671289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn        code->sdkVersion = sdkVersion;
672682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn
6736cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate        code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
6746cce32b6adbb3a9725fc730ba0e0068a74657e60Christopher Tate
675805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        dirStr = env->GetStringUTFChars(obbDir, NULL);
676805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        code->obbPathObj = dirStr;
677805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        code->obbPath = code->obbPathObj.string();
678805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn        env->ReleaseStringUTFChars(obbDir, dirStr);
679805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn
68008d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        jbyte* rawSavedState = NULL;
68108d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        jsize rawSavedSize = 0;
68208d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        if (savedState != NULL) {
68308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            rawSavedState = env->GetByteArrayElements(savedState, NULL);
68408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            rawSavedSize = env->GetArrayLength(savedState);
68508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        }
68608d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
68708d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        code->createActivityFunc(code, rawSavedState, rawSavedSize);
68808d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
68908d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        if (rawSavedState != NULL) {
69008d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
69108d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        }
69269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
69369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
69469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return (jint)code;
69569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
69669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
69769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
69869969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornunloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle)
69969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
700d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("unloadNativeCode_native");
70169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
70269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
70369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        delete code;
70469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
70569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
70669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
70769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
70869969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStart_native(JNIEnv* env, jobject clazz, jint handle)
70969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
710d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onStart_native");
71169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
71269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
71369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStart != NULL) {
714289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onStart(code);
71569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
71669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
71769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
71869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
71969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
72069969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonResume_native(JNIEnv* env, jobject clazz, jint handle)
72169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
722d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onResume_native");
72369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
72469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
72569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onResume != NULL) {
726289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onResume(code);
72769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
72869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
72969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
73069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
73108d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackbornstatic jbyteArray
73269969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle)
73369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
734d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSaveInstanceState_native");
73508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
73608d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    jbyteArray array = NULL;
73708d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
73869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
73969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
74069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onSaveInstanceState != NULL) {
74169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn            size_t len = 0;
74208d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            jbyte* state = (jbyte*)code->callbacks.onSaveInstanceState(code, &len);
74308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            if (len > 0) {
74408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                array = env->NewByteArray(len);
74508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                if (array != NULL) {
74608d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                    env->SetByteArrayRegion(array, 0, len, state);
74708d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                }
74808d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            }
74908d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            if (state != NULL) {
75008d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn                free(state);
75108d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            }
75269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
75369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
75408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
75508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    return array;
75669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
75769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
75869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
75969969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonPause_native(JNIEnv* env, jobject clazz, jint handle)
76069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
761d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onPause_native");
76269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
76369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
76469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onPause != NULL) {
765289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onPause(code);
76669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
76769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
76869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
76969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
77069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
77169969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonStop_native(JNIEnv* env, jobject clazz, jint handle)
77269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
773d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onStop_native");
77469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
77569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
77669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onStop != NULL) {
777289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onStop(code);
77869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
77969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
78069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
78169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
78269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
78308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne HackbornonConfigurationChanged_native(JNIEnv* env, jobject clazz, jint handle)
78408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn{
78508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    LOG_TRACE("onConfigurationChanged_native");
78608d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    if (handle != 0) {
78708d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
78808d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        if (code->callbacks.onConfigurationChanged != NULL) {
78908d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn            code->callbacks.onConfigurationChanged(code);
79008d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn        }
79108d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    }
79208d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn}
79308d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn
79408d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackbornstatic void
79569969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonLowMemory_native(JNIEnv* env, jobject clazz, jint handle)
79669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
797d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onLowMemory_native");
79869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
79969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
80069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onLowMemory != NULL) {
801289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onLowMemory(code);
80269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
80369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
80469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
80569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
80669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic void
80769969e48f2bca9339662dddfacff0bbf6374ed7fDianne HackbornonWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean focused)
80869969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
809d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onWindowFocusChanged_native");
81069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    if (handle != 0) {
81169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        NativeCode* code = (NativeCode*)handle;
81269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        if (code->callbacks.onWindowFocusChanged != NULL) {
813289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onWindowFocusChanged(code, focused ? 1 : 0);
81469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        }
81569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    }
81669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
81769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
81874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
81974323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
82074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
821d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceCreated_native");
82274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
82374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
82474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(surface);
82554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) {
826289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onNativeWindowCreated(code,
82754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
82874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
82974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
83074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
83174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
832d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic int32_t getWindowProp(ANativeWindow* window, int what) {
833d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int value;
834d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    int res = window->query(window, what, &value);
835d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    return res < 0 ? res : value;
836d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
837d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
83874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
83974323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceChanged_native(JNIEnv* env, jobject clazz, jint handle, jobject surface,
84074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        jint format, jint width, jint height)
84174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
842d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceChanged_native");
84374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
84474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
84554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        sp<ANativeWindow> oldNativeWindow = code->nativeWindow;
84654a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        code->setSurface(surface);
84754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (oldNativeWindow != code->nativeWindow) {
8488ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn            if (oldNativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
849289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn                code->callbacks.onNativeWindowDestroyed(code,
8508ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn                        oldNativeWindow.get());
8518ae5a8e7c04c7b204b739dfcd5da9e2e0f83e1ebDianne Hackborn            }
852d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            if (code->nativeWindow != NULL) {
853d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                if (code->callbacks.onNativeWindowCreated != NULL) {
854d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    code->callbacks.onNativeWindowCreated(code,
855d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                            code->nativeWindow.get());
856d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                }
857d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                code->lastWindowWidth = getWindowProp(code->nativeWindow.get(),
858d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                        NATIVE_WINDOW_WIDTH);
859d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                code->lastWindowHeight = getWindowProp(code->nativeWindow.get(),
860d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                        NATIVE_WINDOW_HEIGHT);
861d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            }
862d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        } else {
863d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            // Maybe it resized?
864d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            int32_t newWidth = getWindowProp(code->nativeWindow.get(),
865d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    NATIVE_WINDOW_WIDTH);
866d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            int32_t newHeight = getWindowProp(code->nativeWindow.get(),
867d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    NATIVE_WINDOW_HEIGHT);
868d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            if (newWidth != code->lastWindowWidth
869d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    || newHeight != code->lastWindowHeight) {
870d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                if (code->callbacks.onNativeWindowResized != NULL) {
871d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    code->callbacks.onNativeWindowResized(code,
872d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                            code->nativeWindow.get());
873d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                }
87454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            }
87574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
87674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
87774323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
87874323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
87974323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackbornstatic void
880d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornonSurfaceRedrawNeeded_native(JNIEnv* env, jobject clazz, jint handle)
881d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn{
882d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceRedrawNeeded_native");
883d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (handle != 0) {
884d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
885d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowRedrawNeeded != NULL) {
886d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->callbacks.onNativeWindowRedrawNeeded(code, code->nativeWindow.get());
887d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
888d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
889d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
890d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
891d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic void
89274323fd1ab8eb11beea286d5c213c63e4b803141Dianne HackbornonSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surface)
89374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn{
894d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onSurfaceDestroyed_native");
89574323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    if (handle != 0) {
89674323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
89754a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn        if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) {
898289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onNativeWindowDestroyed(code,
89954a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn                    code->nativeWindow.get());
90074323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        }
90174323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn        code->setSurface(NULL);
90274323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn    }
90374323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn}
90474323fd1ab8eb11beea286d5c213c63e4b803141Dianne Hackborn
905a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
906a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
907a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
908d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onInputChannelCreated_native");
909a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
910a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
911a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        status_t err = code->setInputChannel(channel);
912a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (err != OK) {
913a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            jniThrowException(env, "java/lang/IllegalStateException",
914a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    "Error setting input channel");
915a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn            return;
916a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
917a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->callbacks.onInputQueueCreated != NULL) {
918289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onInputQueueCreated(code,
919a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
920a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
921a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
922a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
923a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
924a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackbornstatic void
925a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne HackbornonInputChannelDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
926a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn{
927d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onInputChannelDestroyed_native");
928a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    if (handle != 0) {
929a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
930a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        if (code->nativeInputQueue != NULL
931a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                && code->callbacks.onInputQueueDestroyed != NULL) {
932289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn            code->callbacks.onInputQueueDestroyed(code,
933a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn                    code->nativeInputQueue);
934a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        }
935a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn        code->setInputChannel(NULL);
936a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    }
937a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn}
938a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn
939d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic void
940d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackbornonContentRectChanged_native(JNIEnv* env, jobject clazz, jint handle,
941d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        jint x, jint y, jint w, jint h)
942d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn{
943d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("onContentRectChanged_native");
944d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (handle != 0) {
945d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
946d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (code->callbacks.onContentRectChanged != NULL) {
947d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            ARect rect;
948d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.left = x;
949d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.top = y;
950d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.right = x+w;
951d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            rect.bottom = y+h;
952d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->callbacks.onContentRectChanged(code, &rect);
953d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
954d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
955d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
956d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
957d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackbornstatic void
958d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne HackborndispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle, jobject eventObj)
959d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn{
960d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    LOG_TRACE("dispatchKeyEvent_native");
961d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    if (handle != 0) {
962d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        NativeCode* code = (NativeCode*)handle;
963d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        if (code->nativeInputQueue != NULL) {
9642c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            KeyEvent* event = code->nativeInputQueue->createKeyEvent();
9651f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            status_t status = android_view_KeyEvent_toNative(env, eventObj, event);
9661f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            if (status) {
9671f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                delete event;
9681f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
9691f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                return;
9701f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            }
971d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            code->nativeInputQueue->dispatchEvent(event);
972d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        }
973d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    }
974d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn}
975d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
9762c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornstatic void
9772c6081ce3593712f30dacd990a97209c791d6cedDianne HackbornfinishPreDispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle,
9782c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        jint seq, jboolean handled)
9792c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn{
9802c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    LOG_TRACE("finishPreDispatchKeyEvent_native");
9812c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    if (handle != 0) {
9822c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        NativeCode* code = (NativeCode*)handle;
9832c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        if (code->nativeInputQueue != NULL) {
9842c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            code->nativeInputQueue->finishPreDispatch(seq, handled ? true : false);
9852c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn        }
9862c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    }
9872c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
9882c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
98969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const JNINativeMethod g_methods[] = {
990805fd7ee0e5dc2939e85c84f78d9890a51982bc0Dianne Hackborn    { "loadNativeCode", "(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)I",
991682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn            (void*)loadNativeCode_native },
99269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
99369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStartNative", "(I)V", (void*)onStart_native },
99469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onResumeNative", "(I)V", (void*)onResume_native },
99508d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    { "onSaveInstanceStateNative", "(I)[B", (void*)onSaveInstanceState_native },
99669969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onPauseNative", "(I)V", (void*)onPause_native },
99769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onStopNative", "(I)V", (void*)onStop_native },
99808d5b8fad8d46ccb64db2fdcb4d66972ec87bf48Dianne Hackborn    { "onConfigurationChangedNative", "(I)V", (void*)onConfigurationChanged_native },
99969969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native },
100069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native },
100154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceCreatedNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceCreated_native },
100254a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceChangedNative", "(ILandroid/view/Surface;III)V", (void*)onSurfaceChanged_native },
1003d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    { "onSurfaceRedrawNeededNative", "(ILandroid/view/Surface;)V", (void*)onSurfaceRedrawNeeded_native },
100454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    { "onSurfaceDestroyedNative", "(I)V", (void*)onSurfaceDestroyed_native },
1005a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelCreatedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelCreated_native },
1006a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn    { "onInputChannelDestroyedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelDestroyed_native },
1007d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    { "onContentRectChangedNative", "(IIIII)V", (void*)onContentRectChanged_native },
1008d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    { "dispatchKeyEventNative", "(ILandroid/view/KeyEvent;)V", (void*)dispatchKeyEvent_native },
10092c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    { "finishPreDispatchKeyEventNative", "(IIZ)V", (void*)finishPreDispatchKeyEvent_native },
101069969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn};
101169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
101269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornstatic const char* const kNativeActivityPathName = "android/app/NativeActivity";
101369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
10143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define FIND_CLASS(var, className) \
10153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->FindClass(className); \
101617cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro        LOG_FATAL_IF(! var, "Unable to find class %s", className);
10173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
10183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
10193c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
10203c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn        LOG_FATAL_IF(! var, "Unable to find method" methodName);
10213c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
102269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackbornint register_android_app_NativeActivity(JNIEnv* env)
102369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn{
10245baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    //ALOGD("register_android_app_NativeActivity");
102517cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    jclass clazz;
102617cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    FIND_CLASS(clazz, kNativeActivityPathName);
102769969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
10283c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.dispatchUnhandledKeyEvent,
102917cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro            clazz,
10303915bb845b032dc184dba5e60970b803390ca3edJeff Brown            "dispatchUnhandledKeyEvent", "(Landroid/view/KeyEvent;)Z");
10312c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.preDispatchKeyEvent,
103217cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro            clazz,
10332c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn            "preDispatchKeyEvent", "(Landroid/view/KeyEvent;I)V");
103454a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
1035db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.finish,
103617cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro            clazz,
1037db28a94d499f995b467b07cee5c9b9119f538b1cDianne Hackborn            "finish", "()V");
103854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFlags,
103917cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro            clazz,
104054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFlags", "(II)V");
104154a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.setWindowFormat,
104217cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro            clazz,
104354a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn            "setWindowFormat", "(I)V");
1044d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.showIme,
104517cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro            clazz,
1046d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            "showIme", "(I)V");
1047d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn    GET_METHOD_ID(gNativeActivityClassInfo.hideIme,
104817cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro            clazz,
1049d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            "hideIme", "(I)V");
105054a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn
105169969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn    return AndroidRuntime::registerNativeMethods(
105269969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        env, kNativeActivityPathName,
105369969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn        g_methods, NELEM(g_methods));
105469969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn}
105569969e48f2bca9339662dddfacff0bbf6374ed7fDianne Hackborn
1056a95e4cb62f3642cb190d032dbf7dc40d9ecc6973Dianne Hackborn} // namespace android
1057