summaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-07-13 19:50:36 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2010-07-13 19:50:36 -0700
commit2388ad9eef109fa7f63c196c819c83f0376f0645 (patch)
tree19c965b6d7efb893604fc448cebc9380ebb60fb6 /native
parentfc6d300f408959b11f86623ea7a0ce547ded3563 (diff)
parentf8d9379bd834573feca085284970cf686993c330 (diff)
downloadframeworks_base-2388ad9eef109fa7f63c196c819c83f0376f0645.zip
frameworks_base-2388ad9eef109fa7f63c196c819c83f0376f0645.tar.gz
frameworks_base-2388ad9eef109fa7f63c196c819c83f0376f0645.tar.bz2
am f8d9379b: am d76b67c3: IME events are now dispatched to native applications.
Merge commit 'f8d9379bd834573feca085284970cf686993c330' * commit 'f8d9379bd834573feca085284970cf686993c330': IME events are now dispatched to native applications.
Diffstat (limited to 'native')
-rw-r--r--native/android/input.cpp62
-rw-r--r--native/android/native_activity.cpp8
-rw-r--r--native/glue/threaded_app/threaded_app.c61
-rw-r--r--native/include/android/native_activity.h42
-rw-r--r--native/include/android_glue/threaded_app.h32
5 files changed, 152 insertions, 53 deletions
diff --git a/native/android/input.cpp b/native/android/input.cpp
index 89d53e2..a4dde51 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -22,6 +22,8 @@
#include <ui/InputTransport.h>
#include <utils/PollLoop.h>
+#include <android_runtime/android_app_NativeActivity.h>
+
#include <poll.h>
using android::InputEvent;
@@ -187,65 +189,21 @@ float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_i
void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
ALooper_callbackFunc* callback, void* data) {
- queue->setPollLoop(static_cast<android::PollLoop*>(looper));
- ALooper_addFd(looper, queue->getConsumer().getChannel()->getReceivePipeFd(),
- POLLIN, callback, data);
+ queue->attachLooper(looper, callback, data);
}
void AInputQueue_detachLooper(AInputQueue* queue) {
- queue->getPollLoop()->removeCallback(
- queue->getConsumer().getChannel()->getReceivePipeFd());
+ queue->detachLooper();
}
int AInputQueue_hasEvents(AInputQueue* queue) {
- struct pollfd pfd;
-
- pfd.fd = queue->getConsumer().getChannel()->getReceivePipeFd();
- pfd.events = POLLIN;
- pfd.revents = 0;
-
- int nfd = poll(&pfd, 1, 0);
- if (nfd <= 0) return nfd;
- return pfd.revents == POLLIN ? 1 : -1;
+ return queue->hasEvents();
}
int32_t AInputQueue_getEvent(AInputQueue* queue, AInputEvent** outEvent) {
- *outEvent = NULL;
-
- int32_t res = queue->getConsumer().receiveDispatchSignal();
- if (res != android::OK) {
- LOGE("channel '%s' ~ Failed to receive dispatch signal. status=%d",
- queue->getConsumer().getChannel()->getName().string(), res);
- return -1;
- }
-
- InputEvent* myEvent = NULL;
- res = queue->consume(&myEvent);
- if (res != android::OK) {
- LOGW("channel '%s' ~ Failed to consume input event. status=%d",
- queue->getConsumer().getChannel()->getName().string(), res);
- queue->getConsumer().sendFinishedSignal();
- return -1;
- }
-
- *outEvent = myEvent;
- return 0;
-}
-
-void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event,
- int handled) {
- if (!handled && ((InputEvent*)event)->getType() == INPUT_EVENT_TYPE_KEY
- && ((KeyEvent*)event)->hasDefaultAction()) {
- // The app didn't handle this, but it may have a default action
- // associated with it. We need to hand this back to Java to be
- // executed.
- queue->doDefaultKey((KeyEvent*)event);
- return;
- }
-
- int32_t res = queue->getConsumer().sendFinishedSignal();
- if (res != android::OK) {
- LOGW("Failed to send finished signal on channel '%s'. status=%d",
- queue->getConsumer().getChannel()->getName().string(), res);
- }
+ return queue->getEvent(outEvent);
+}
+
+void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled) {
+ queue->finishEvent(event, handled != 0);
}
diff --git a/native/android/native_activity.cpp b/native/android/native_activity.cpp
index 509cc33..0c6823a 100644
--- a/native/android/native_activity.cpp
+++ b/native/android/native_activity.cpp
@@ -29,3 +29,11 @@ void ANativeActivity_setWindowFlags(ANativeActivity* activity,
uint32_t addFlags, uint32_t removeFlags) {
android_NativeActivity_setWindowFlags(activity, addFlags, addFlags|removeFlags);
}
+
+void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags) {
+ android_NativeActivity_showSoftInput(activity, flags);
+}
+
+void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags) {
+ android_NativeActivity_hideSoftInput(activity, flags);
+}
diff --git a/native/glue/threaded_app/threaded_app.c b/native/glue/threaded_app/threaded_app.c
index 2411e93..452c735 100644
--- a/native/glue/threaded_app/threaded_app.c
+++ b/native/glue/threaded_app/threaded_app.c
@@ -18,6 +18,7 @@
#include <jni.h>
#include <errno.h>
+#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
@@ -75,6 +76,19 @@ int32_t android_app_exec_cmd(struct android_app* android_app, int8_t cmd) {
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
+
+ case APP_CMD_WINDOW_REDRAW_NEEDED:
+ LOGI("APP_CMD_WINDOW_REDRAW_NEEDED\n");
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->redrawNeeded = 0;
+ pthread_cond_broadcast(&android_app->cond);
+ pthread_mutex_unlock(&android_app->mutex);
+ break;
+
+ case APP_CMD_CONTENT_RECT_CHANGED:
+ LOGI("APP_CMD_CONTENT_RECT_CHANGED\n");
+ android_app->contentRect = android_app->pendingContentRect;
+ break;
case APP_CMD_DESTROY:
LOGI("APP_CMD_DESTROY\n");
@@ -133,6 +147,12 @@ static struct android_app* android_app_create(ANativeActivity* activity) {
}
android_app->msgread = msgpipe[0];
android_app->msgwrite = msgpipe[1];
+ int result = fcntl(android_app->msgread, F_SETFL, O_NONBLOCK);
+ if (result != 0) LOGW("Could not make message read pipe "
+ "non-blocking: %s", strerror(errno));
+ result = fcntl(android_app->msgwrite, F_SETFL, O_NONBLOCK);
+ if (result != 0) LOGW("Could not make message write pipe "
+ "non-blocking: %s", strerror(errno));
pthread_attr_t attr;
pthread_attr_init(&attr);
@@ -184,6 +204,23 @@ static void android_app_set_activity_state(struct android_app* android_app, int8
pthread_mutex_unlock(&android_app->mutex);
}
+static void android_app_wait_redraw(struct android_app* android_app) {
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->redrawNeeded = 1;
+ android_app_write_cmd(android_app, APP_CMD_WINDOW_REDRAW_NEEDED);
+ while (android_app->redrawNeeded) {
+ pthread_cond_wait(&android_app->cond, &android_app->mutex);
+ }
+ pthread_mutex_unlock(&android_app->mutex);
+}
+
+static void android_app_set_content_rect(struct android_app* android_app, const ARect* rect) {
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->pendingContentRect = *rect;
+ android_app_write_cmd(android_app, APP_CMD_CONTENT_RECT_CHANGED);
+ pthread_mutex_unlock(&android_app->mutex);
+}
+
static void android_app_free(struct android_app* android_app) {
pthread_mutex_lock(&android_app->mutex);
android_app_write_cmd(android_app, APP_CMD_DESTROY);
@@ -231,6 +268,8 @@ static void onStop(ANativeActivity* activity) {
static void onLowMemory(ANativeActivity* activity) {
LOGI("LowMemory: %p\n", activity);
+ android_app_write_cmd((struct android_app*)activity->instance,
+ APP_CMD_LOW_MEMORY);
}
static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
@@ -244,6 +283,23 @@ static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* wind
android_app_set_window((struct android_app*)activity->instance, window);
}
+static void onNativeWindowResized(ANativeActivity* activity, ANativeWindow* window) {
+ LOGI("NativeWindowResized: %p -- %p\n", activity, window);
+ android_app_write_cmd((struct android_app*)activity->instance,
+ APP_CMD_WINDOW_RESIZED);
+}
+
+static void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window) {
+ LOGI("NativeWindowRedrawNeeded: %p -- %p\n", activity, window);
+ android_app_wait_redraw((struct android_app*)activity->instance);
+}
+
+static void onContentRectChanged(ANativeActivity* activity, const ARect* rect) {
+ LOGI("ContentRectChanged: %p -- (%d,%d)-(%d,%d)\n", activity, rect->left,
+ rect->top, rect->right, rect->bottom);
+ android_app_set_content_rect((struct android_app*)activity->instance, rect);
+}
+
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
LOGI("NativeWindowDestroyed: %p -- %p\n", activity, window);
android_app_set_window((struct android_app*)activity->instance, NULL);
@@ -268,12 +324,15 @@ void ANativeActivity_onCreate(ANativeActivity* activity,
activity->callbacks->onSaveInstanceState = onSaveInstanceState;
activity->callbacks->onPause = onPause;
activity->callbacks->onStop = onStop;
- activity->callbacks->onLowMemory = onLowMemory;
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
+ activity->callbacks->onNativeWindowResized = onNativeWindowResized;
+ activity->callbacks->onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded;
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
+ activity->callbacks->onContentRectChanged = onContentRectChanged;
+ activity->callbacks->onLowMemory = onLowMemory;
activity->instance = android_app_create(activity);
}
diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h
index d0ff052..ea6f05f 100644
--- a/native/include/android/native_activity.h
+++ b/native/include/android/native_activity.h
@@ -147,6 +147,21 @@ typedef struct ANativeActivityCallbacks {
void (*onNativeWindowCreated)(ANativeActivity* activity, ANativeWindow* window);
/**
+ * The drawing window for this native activity has been resized. You should
+ * retrieve the new size from the window and ensure that your rendering in
+ * it now matches.
+ */
+ void (*onNativeWindowResized)(ANativeActivity* activity, ANativeWindow* window);
+
+ /**
+ * The drawing window for this native activity needs to be redrawn. To avoid
+ * transient artifacts during screen changes (such resizing after rotation),
+ * applications should not return from this function until they have finished
+ * drawing their window in its current state.
+ */
+ void (*onNativeWindowRedrawNeeded)(ANativeActivity* activity, ANativeWindow* window);
+
+ /**
* The drawing window for this native activity is going to be destroyed.
* You MUST ensure that you do not touch the window object after returning
* from this function: in the common case of drawing to the window from
@@ -170,6 +185,11 @@ typedef struct ANativeActivityCallbacks {
void (*onInputQueueDestroyed)(ANativeActivity* activity, AInputQueue* queue);
/**
+ * The rectangle in the window in which content should be placed has changed.
+ */
+ void (*onContentRectChanged)(ANativeActivity* activity, const ARect* rect);
+
+ /**
* The system is running low on memory. Use this callback to release
* resources you do not need, to help the system avoid killing more
* important processes.
@@ -197,6 +217,28 @@ void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format);
void ANativeActivity_setWindowFlags(ANativeActivity* activity,
uint32_t addFlags, uint32_t removeFlags);
+/**
+ * Flags for ANativeActivity_showSoftInput; see the Java InputMethodManager
+ * API for documentation.
+ */
+enum {
+ ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT = 0x0001,
+ ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002,
+};
+
+void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags);
+
+/**
+ * Flags for ANativeActivity_hideSoftInput; see the Java InputMethodManager
+ * API for documentation.
+ */
+enum {
+ ANATIVEACTIVITY_HIDE_SOFT_INPUT_IMPLICIT_ONLY = 0x0001,
+ ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002,
+};
+
+void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags);
+
#ifdef __cplusplus
};
#endif
diff --git a/native/include/android_glue/threaded_app.h b/native/include/android_glue/threaded_app.h
index adfdbea..2b58e9c 100644
--- a/native/include/android_glue/threaded_app.h
+++ b/native/include/android_glue/threaded_app.h
@@ -48,6 +48,10 @@ struct android_app {
// When non-NULL, this is the window surface that the app can draw in.
ANativeWindow* window;
+ // Current content rectangle of the window; this is the area where the
+ // window's content should be placed to be seen by the user.
+ ARect contentRect;
+
// Current state of the app's activity. May be either APP_CMD_START,
// APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below.
int activityState;
@@ -69,8 +73,10 @@ struct android_app {
int running;
int destroyed;
+ int redrawNeeded;
AInputQueue* pendingInputQueue;
ANativeWindow* pendingWindow;
+ ARect pendingContentRect;
};
enum {
@@ -105,6 +111,26 @@ enum {
APP_CMD_WINDOW_CHANGED,
/**
+ * Command from main thread: the current ANativeWindow has been resized.
+ * Please redraw with its new size.
+ */
+ APP_CMD_WINDOW_RESIZED,
+
+ /**
+ * Command from main thread: the system needs that the current ANativeWindow
+ * be redrawn. You should redraw the window before handing this to
+ * android_app_exec_cmd() in order to avoid transient drawing glitches.
+ */
+ APP_CMD_WINDOW_REDRAW_NEEDED,
+
+ /**
+ * Command from main thread: the content area of the window has changed,
+ * such as from the soft input window being shown or hidden. You can
+ * find the new content rect in android_app::contentRect.
+ */
+ APP_CMD_CONTENT_RECT_CHANGED,
+
+ /**
* Command from main thread: the app's activity window has gained
* input focus.
*/
@@ -117,6 +143,12 @@ enum {
APP_CMD_LOST_FOCUS,
/**
+ * Command from main thread: the system is running low on memory.
+ * Try to reduce your memory use.
+ */
+ APP_CMD_LOW_MEMORY,
+
+ /**
* Command from main thread: the app's activity has been started.
*/
APP_CMD_START,