diff options
Diffstat (limited to 'native')
-rw-r--r-- | native/android/input.cpp | 4 | ||||
-rw-r--r-- | native/android/looper.cpp | 75 | ||||
-rw-r--r-- | native/android/sensor.cpp | 6 | ||||
-rw-r--r-- | native/include/android/input.h | 2 | ||||
-rw-r--r-- | native/include/android/looper.h | 189 | ||||
-rw-r--r-- | native/include/android/sensor.h | 2 |
6 files changed, 168 insertions, 110 deletions
diff --git a/native/android/input.cpp b/native/android/input.cpp index 57f0072..c753aa5 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -20,7 +20,7 @@ #include <android/input.h> #include <ui/Input.h> #include <ui/InputTransport.h> -#include <utils/PollLoop.h> +#include <utils/Looper.h> #include <utils/RefBase.h> #include <utils/Vector.h> @@ -250,7 +250,7 @@ float AMotionEvent_getHistoricalOrientation(AInputEvent* motion_event, size_t po void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper, - int ident, ALooper_callbackFunc* callback, void* data) { + int ident, ALooper_callbackFunc callback, void* data) { queue->attachLooper(looper, ident, callback, data); } diff --git a/native/android/looper.cpp b/native/android/looper.cpp index 0aeed77..9f5cda9 100644 --- a/native/android/looper.cpp +++ b/native/android/looper.cpp @@ -18,65 +18,56 @@ #include <utils/Log.h> #include <android/looper.h> -#include <utils/PollLoop.h> +#include <utils/Looper.h> -using android::PollLoop; +using android::Looper; using android::sp; ALooper* ALooper_forThread() { - return PollLoop::getForThread().get(); + return Looper::getForThread().get(); } -ALooper* ALooper_prepare(int32_t opts) { - bool allowFds = (opts&ALOOPER_PREPARE_ALLOW_NON_CALLBACKS) != 0; - sp<PollLoop> loop = PollLoop::getForThread(); - if (loop == NULL) { - loop = new PollLoop(allowFds); - PollLoop::setForThread(loop); - } - if (loop->getAllowNonCallbacks() != allowFds) { - LOGW("ALooper_prepare again with different ALOOPER_PREPARE_ALLOW_NON_CALLBACKS"); - } - return loop.get(); +ALooper* ALooper_prepare(int opts) { + return Looper::prepare(opts).get(); } -int32_t ALooper_pollOnce(int timeoutMillis, int* outEvents, void** outData) { - sp<PollLoop> loop = PollLoop::getForThread(); - if (loop == NULL) { - LOGW("ALooper_pollOnce: No looper for this thread!"); - return -1; - } - return loop->pollOnce(timeoutMillis, outEvents, outData); +void ALooper_acquire(ALooper* looper) { + static_cast<Looper*>(looper)->incStrong((void*)ALooper_acquire); } -int32_t ALooper_pollAll(int timeoutMillis, int* outEvents, void** outData) { - sp<PollLoop> loop = PollLoop::getForThread(); - if (loop == NULL) { - LOGW("ALooper_pollOnce: No looper for this thread!"); - return -1; - } - - int32_t result; - while ((result = loop->pollOnce(timeoutMillis, outEvents, outData)) == ALOOPER_POLL_CALLBACK) { - ; +void ALooper_release(ALooper* looper) { + static_cast<Looper*>(looper)->decStrong((void*)ALooper_acquire); +} + +int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { + sp<Looper> looper = Looper::getForThread(); + if (looper == NULL) { + LOGE("ALooper_pollOnce: No looper for this thread!"); + return ALOOPER_POLL_ERROR; } - - return result; + + return looper->pollOnce(timeoutMillis, outFd, outEvents, outData); } -void ALooper_acquire(ALooper* looper) { - static_cast<PollLoop*>(looper)->incStrong((void*)ALooper_acquire); +int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { + sp<Looper> looper = Looper::getForThread(); + if (looper == NULL) { + LOGE("ALooper_pollAll: No looper for this thread!"); + return ALOOPER_POLL_ERROR; + } + + return looper->pollAll(timeoutMillis, outFd, outEvents, outData); } -void ALooper_release(ALooper* looper) { - static_cast<PollLoop*>(looper)->decStrong((void*)ALooper_acquire); +void ALooper_wake(ALooper* looper) { + static_cast<Looper*>(looper)->wake(); } -void ALooper_addFd(ALooper* looper, int fd, int ident, int events, - ALooper_callbackFunc* callback, void* data) { - static_cast<PollLoop*>(looper)->setLooperCallback(fd, ident, events, callback, data); +int ALooper_addFd(ALooper* looper, int fd, int ident, int events, + ALooper_callbackFunc callback, void* data) { + return static_cast<Looper*>(looper)->addFd(fd, ident, events, callback, data); } -int32_t ALooper_removeFd(ALooper* looper, int fd) { - return static_cast<PollLoop*>(looper)->removeCallback(fd) ? 1 : 0; +int ALooper_removeFd(ALooper* looper, int fd) { + return static_cast<Looper*>(looper)->removeFd(fd); } diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp index cf7635d..76c6eda 100644 --- a/native/android/sensor.cpp +++ b/native/android/sensor.cpp @@ -21,7 +21,7 @@ #include <android/sensor.h> #include <utils/RefBase.h> -#include <utils/PollLoop.h> +#include <utils/Looper.h> #include <utils/Timers.h> #include <gui/Sensor.h> @@ -60,12 +60,12 @@ ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type } ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager, - ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data) + ALooper* looper, int ident, ALooper_callbackFunc callback, void* data) { sp<SensorEventQueue> queue = static_cast<SensorManager*>(manager)->createEventQueue(); if (queue != 0) { - ALooper_addFd(looper, queue->getFd(), ident, POLLIN, callback, data); + ALooper_addFd(looper, queue->getFd(), ident, ALOOPER_EVENT_INPUT, callback, data); queue->looper = looper; queue->incStrong(manager); } diff --git a/native/include/android/input.h b/native/include/android/input.h index 9da122b..c1134bf 100644 --- a/native/include/android/input.h +++ b/native/include/android/input.h @@ -645,7 +645,7 @@ typedef struct AInputQueue AInputQueue; * ALooper_addFd() for information on the ident, callback, and data params. */ void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper, - int ident, ALooper_callbackFunc* callback, void* data); + int ident, ALooper_callbackFunc callback, void* data); /* * Remove the input queue from the looper it is currently attached to. diff --git a/native/include/android/looper.h b/native/include/android/looper.h index 287bcd5..a63b744 100644 --- a/native/include/android/looper.h +++ b/native/include/android/looper.h @@ -18,8 +18,6 @@ #ifndef ANDROID_LOOPER_H #define ANDROID_LOOPER_H -#include <poll.h> - #ifdef __cplusplus extern "C" { #endif @@ -41,25 +39,14 @@ struct ALooper; typedef struct ALooper ALooper; /** - * For callback-based event loops, this is the prototype of the function - * that is called. It is given the file descriptor it is associated with, - * a bitmask of the poll events that were triggered (typically POLLIN), and - * the data pointer that was originally supplied. - * - * Implementations should return 1 to continue receiving callbacks, or 0 - * to have this file descriptor and callback unregistered from the looper. - */ -typedef int ALooper_callbackFunc(int fd, int events, void* data); - -/** - * Return the ALooper associated with the calling thread, or NULL if + * Returns the looper associated with the calling thread, or NULL if * there is not one. */ ALooper* ALooper_forThread(); enum { /** - * Option for ALooper_prepare: this ALooper will accept calls to + * Option for ALooper_prepare: this looper will accept calls to * ALooper_addFd() that do not have a callback (that is provide NULL * for the callback). In this case the caller of ALooper_pollOnce() * or ALooper_pollAll() MUST check the return from these functions to @@ -69,108 +56,188 @@ enum { }; /** - * Prepare an ALooper associated with the calling thread, and return it. - * If the thread already has an ALooper, it is returned. Otherwise, a new + * Prepares a looper associated with the calling thread, and returns it. + * If the thread already has a looper, it is returned. Otherwise, a new * one is created, associated with the thread, and returned. * * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0. */ -ALooper* ALooper_prepare(int32_t opts); +ALooper* ALooper_prepare(int opts); enum { /** - * Result from ALooper_pollOnce() and ALooper_pollAll(): one or - * more callbacks were executed. + * Result from ALooper_pollOnce() and ALooper_pollAll(): + * The poll was awoken using wake() before the timeout expired + * and no callbacks were executed and no other file descriptors were ready. */ - ALOOPER_POLL_CALLBACK = -1, - + ALOOPER_POLL_WAKE = -1, + + /** + * Result from ALooper_pollOnce() and ALooper_pollAll(): + * One or more callbacks were executed. + */ + ALOOPER_POLL_CALLBACK = -2, + /** - * Result from ALooper_pollOnce() and ALooper_pollAll(): the - * timeout expired. + * Result from ALooper_pollOnce() and ALooper_pollAll(): + * The timeout expired. */ - ALOOPER_POLL_TIMEOUT = -2, - + ALOOPER_POLL_TIMEOUT = -3, + /** - * Result from ALooper_pollOnce() and ALooper_pollAll(): an error - * occurred. + * Result from ALooper_pollOnce() and ALooper_pollAll(): + * An error occurred. */ - ALOOPER_POLL_ERROR = -3, + ALOOPER_POLL_ERROR = -4, }; /** - * Wait for events to be available, with optional timeout in milliseconds. + * Acquire a reference on the given ALooper object. This prevents the object + * from being deleted until the reference is removed. This is only needed + * to safely hand an ALooper from one thread to another. + */ +void ALooper_acquire(ALooper* looper); + +/** + * Remove a reference that was previously acquired with ALooper_acquire(). + */ +void ALooper_release(ALooper* looper); + +/** + * Flags for file descriptor events that a looper can monitor. + * + * These flag bits can be combined to monitor multiple events at once. + */ +enum { + /** + * The file descriptor is available for read operations. + */ + ALOOPER_EVENT_INPUT = 1 << 0, + + /** + * The file descriptor is available for write operations. + */ + ALOOPER_EVENT_OUTPUT = 1 << 1, + + /** + * The file descriptor has encountered an error condition. + * + * The looper always sends notifications about errors; it is not necessary + * to specify this event flag in the requested event set. + */ + ALOOPER_EVENT_ERROR = 1 << 2, + + /** + * The file descriptor was hung up. + * For example, indicates that the remote end of a pipe or socket was closed. + * + * The looper always sends notifications about hangups; it is not necessary + * to specify this event flag in the requested event set. + */ + ALOOPER_EVENT_HANGUP = 1 << 3, +}; + +/** + * For callback-based event loops, this is the prototype of the function + * that is called. It is given the file descriptor it is associated with, + * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT), + * and the data pointer that was originally supplied. + * + * Implementations should return 1 to continue receiving callbacks, or 0 + * to have this file descriptor and callback unregistered from the looper. + */ +typedef int (*ALooper_callbackFunc)(int fd, int events, void* data); + +/** + * Waits for events to be available, with optional timeout in milliseconds. * Invokes callbacks for all file descriptors on which an event occurred. * * If the timeout is zero, returns immediately without blocking. * If the timeout is negative, waits indefinitely until an event appears. * - * Returns ALOOPER_POLL_CALLBACK if a callback was invoked. + * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before + * the timeout expired and no callbacks were invoked and no other file + * descriptors were ready. + * + * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked. * * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given * timeout expired. * - * Returns ALOPER_POLL_ERROR if an error occurred. + * Returns ALOOPER_POLL_ERROR if an error occurred. * * Returns a value >= 0 containing an identifier if its file descriptor has data * and it has no callback function (requiring the caller here to handle it). - * In this (and only this) case outEvents and outData will contain the poll - * events and data associated with the fd. + * In this (and only this) case outFd, outEvents and outData will contain the poll + * events and data associated with the fd, otherwise they will be set to NULL. * * This method does not return until it has finished invoking the appropriate callbacks * for all file descriptors that were signalled. */ -int32_t ALooper_pollOnce(int timeoutMillis, int* outEvents, void** outData); +int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData); /** * Like ALooper_pollOnce(), but performs all pending callbacks until all * data has been consumed or a file descriptor is available with no callback. * This function will never return ALOOPER_POLL_CALLBACK. */ -int32_t ALooper_pollAll(int timeoutMillis, int* outEvents, void** outData); - -/** - * Acquire a reference on the given ALooper object. This prevents the object - * from being deleted until the reference is removed. This is only needed - * to safely hand an ALooper from one thread to another. - */ -void ALooper_acquire(ALooper* looper); +int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData); /** - * Remove a reference that was previously acquired with ALooper_acquire(). + * Wakes the poll asynchronously. + * + * This method can be called on any thread. + * This method returns immediately. */ -void ALooper_release(ALooper* looper); +void ALooper_wake(ALooper* looper); /** - * Add a new file descriptor to be polled by the looper. If the same file - * descriptor was previously added, it is replaced. + * Adds a new file descriptor to be polled by the looper. + * If the same file descriptor was previously added, it is replaced. * * "fd" is the file descriptor to be added. - * "ident" is an identifier for this event, which is returned from - * ALooper_pollOnce(). Must be >= 0, or ALOOPER_POLL_CALLBACK if - * providing a non-NULL callback. - * "events" are the poll events to wake up on. Typically this is POLLIN. - * "callback" is the function to call when there is an event on the file - * descriptor. + * "ident" is an identifier for this event, which is returned from ALooper_pollOnce(). + * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback. + * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT. + * "callback" is the function to call when there is an event on the file descriptor. * "data" is a private data pointer to supply to the callback. * * There are two main uses of this function: * - * (1) If "callback" is non-NULL, then - * this function will be called when there is data on the file descriptor. It - * should execute any events it has pending, appropriately reading from the - * file descriptor. The 'ident' is ignored in this case. + * (1) If "callback" is non-NULL, then this function will be called when there is + * data on the file descriptor. It should execute any events it has pending, + * appropriately reading from the file descriptor. The 'ident' is ignored in this case. * * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce * when its file descriptor has data available, requiring the caller to take * care of processing it. + * + * Returns 1 if the file descriptor was added or -1 if an error occurred. + * + * This method can be called on any thread. + * This method may block briefly if it needs to wake the poll. */ -void ALooper_addFd(ALooper* looper, int fd, int ident, int events, - ALooper_callbackFunc* callback, void* data); +int ALooper_addFd(ALooper* looper, int fd, int ident, int events, + ALooper_callbackFunc callback, void* data); /** - * Remove a previously added file descriptor from the looper. + * Removes a previously added file descriptor from the looper. + * + * When this method returns, it is safe to close the file descriptor since the looper + * will no longer have a reference to it. However, it is possible for the callback to + * already be running or for it to run one last time if the file descriptor was already + * signalled. Calling code is responsible for ensuring that this case is safely handled. + * For example, if the callback takes care of removing itself during its own execution either + * by returning 0 or by calling this method, then it can be guaranteed to not be invoked + * again at any later time unless registered anew. + * + * Returns 1 if the file descriptor was removed, 0 if none was previously registered + * or -1 if an error occurred. + * + * This method can be called on any thread. + * This method may block briefly if it needs to wake the poll. */ -int32_t ALooper_removeFd(ALooper* looper, int fd); +int ALooper_removeFd(ALooper* looper, int fd); #ifdef __cplusplus }; diff --git a/native/include/android/sensor.h b/native/include/android/sensor.h index a102d43..f163f18 100644 --- a/native/include/android/sensor.h +++ b/native/include/android/sensor.h @@ -166,7 +166,7 @@ ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type * Creates a new sensor event queue and associate it with a looper. */ ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager, - ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data); + ALooper* looper, int ident, ALooper_callbackFunc callback, void* data); /* * Destroys the event queue and free all resources associated to it. |