Add new native Looper API.
This allows us to avoid exposing the file descriptor of
the event queue; instead, you attach an event queue to
a looper. This will also should allow native apps to be
written without the need for a separate thread, by attaching
the event queue to the main thread's looper and scheduling
their own messages there.
Change-Id: I38489282635895ae2cbfacb88599c1b1cad9b239
diff --git a/native/android/Android.mk b/native/android/Android.mk
index fe8ed00..376c64f 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -8,6 +8,7 @@
LOCAL_SRC_FILES:= \
activity.cpp \
input.cpp \
+ looper.cpp \
native_window.cpp
LOCAL_SHARED_LIBRARIES := \
diff --git a/native/android/input.cpp b/native/android/input.cpp
index 8498840..015a1ce 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -20,6 +20,7 @@
#include <android/input.h>
#include <ui/Input.h>
#include <ui/InputTransport.h>
+#include <utils/PollLoop.h>
#include <poll.h>
@@ -184,8 +185,16 @@
pointer_index, history_index);
}
-int AInputQueue_getFd(AInputQueue* queue) {
- return queue->getConsumer().getChannel()->getReceivePipeFd();
+void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
+ ALooper_callbackFunc callback, void* data) {
+ queue->setPollLoop(static_cast<android::PollLoop*>(looper));
+ ALooper_setCallback(looper, queue->getConsumer().getChannel()->getReceivePipeFd(),
+ POLLIN, callback, data);
+}
+
+void AInputQueue_detachLooper(AInputQueue* queue) {
+ queue->getPollLoop()->removeCallback(
+ queue->getConsumer().getChannel()->getReceivePipeFd());
}
int AInputQueue_hasEvents(AInputQueue* queue) {
diff --git a/native/android/looper.cpp b/native/android/looper.cpp
new file mode 100644
index 0000000..6e78bbd
--- /dev/null
+++ b/native/android/looper.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ALooper"
+#include <utils/Log.h>
+
+#include <android/looper.h>
+#include <utils/PollLoop.h>
+
+using android::PollLoop;
+using android::sp;
+
+ALooper* ALooper_forThread() {
+ return PollLoop::getForThread().get();
+}
+
+ALooper* ALooper_prepare() {
+ sp<PollLoop> loop = PollLoop::getForThread();
+ if (loop == NULL) {
+ loop = new PollLoop();
+ PollLoop::setForThread(loop);
+ }
+ return loop.get();
+}
+
+int32_t ALooper_pollOnce(int timeoutMillis) {
+ sp<PollLoop> loop = PollLoop::getForThread();
+ if (loop == NULL) {
+ LOGW("ALooper_pollOnce: No looper for this thread!");
+ return -1;
+ }
+ return loop->pollOnce(timeoutMillis) ? 1 : 0;
+}
+
+void ALooper_acquire(ALooper* looper) {
+ static_cast<PollLoop*>(looper)->incStrong((void*)ALooper_acquire);
+}
+
+void ALooper_release(ALooper* looper) {
+ static_cast<PollLoop*>(looper)->decStrong((void*)ALooper_acquire);
+}
+
+void ALooper_setCallback(ALooper* looper, int fd, int events,
+ ALooper_callbackFunc* callback, void* data) {
+ static_cast<PollLoop*>(looper)->setLooperCallback(fd, events, callback, data);
+}
+
+int32_t ALooper_removeCallback(ALooper* looper, int fd) {
+ return static_cast<PollLoop*>(looper)->removeCallback(fd) ? 1 : 0;
+}