diff options
author | Jeff Brown <jeffbrown@google.com> | 2015-02-26 14:43:53 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2015-03-11 15:00:34 -0700 |
commit | 6c7b41adf9e937a66880b8906389760f3fc82a08 (patch) | |
tree | 35076e657b6527ebb9860c75ec78aaf8c07bcf75 /core | |
parent | 044644c71722c8094a69d7bc8e68f73032bf5c7c (diff) | |
download | frameworks_base-6c7b41adf9e937a66880b8906389760f3fc82a08.zip frameworks_base-6c7b41adf9e937a66880b8906389760f3fc82a08.tar.gz frameworks_base-6c7b41adf9e937a66880b8906389760f3fc82a08.tar.bz2 |
Rename Looper::isIdling() to isPolling() to resolve confusion.
The loop isn't technically idle at this time, it's just checking
whether any file descriptors have pending events. However it's
still a good signal as to whether the loop is alive.
Added a real isIdle() function.
Bug: 19532373
Change-Id: Idd273e8774f469ccafb00d560818cf279dfd6ba6
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/hardware/camera2/legacy/RequestHandlerThread.java | 8 | ||||
-rw-r--r-- | core/java/android/os/Looper.java | 20 | ||||
-rw-r--r-- | core/java/android/os/MessageQueue.java | 119 | ||||
-rw-r--r-- | core/jni/android_os_MessageQueue.cpp | 6 |
4 files changed, 90 insertions, 63 deletions
diff --git a/core/java/android/hardware/camera2/legacy/RequestHandlerThread.java b/core/java/android/hardware/camera2/legacy/RequestHandlerThread.java index 0699ffb..e19ebf2 100644 --- a/core/java/android/hardware/camera2/legacy/RequestHandlerThread.java +++ b/core/java/android/hardware/camera2/legacy/RequestHandlerThread.java @@ -96,15 +96,15 @@ public class RequestHandlerThread extends HandlerThread { // Blocks until thread is idling public void waitUntilIdle() { Handler handler = waitAndGetHandler(); - Looper looper = handler.getLooper(); - if (looper.isIdling()) { + MessageQueue queue = handler.getLooper().getQueue(); + if (queue.isIdle()) { return; } mIdle.close(); - looper.getQueue().addIdleHandler(mIdleHandler); + queue.addIdleHandler(mIdleHandler); // Ensure that the idle handler gets run even if the looper already went idle handler.sendEmptyMessage(MSG_POKE_IDLE_HANDLER); - if (looper.isIdling()) { + if (queue.isIdle()) { return; } mIdle.block(); diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index 6d7c9cf..8b99196 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -50,6 +50,16 @@ import android.util.Printer; * }</pre> */ public final class Looper { + /* + * API Implementation Note: + * + * This class contains the code required to set up and manage an event loop + * based on MessageQueue. APIs that affect the state of the queue should be + * defined on MessageQueue or Handler rather than on Looper itself. For example, + * idle handlers and sync barriers are defined on the queue whereas preparing the + * thread, looping and quitting are defined on the looper. + */ + private static final String TAG = "Looper"; // sThreadLocal.get() will return null unless you've called prepare(). @@ -286,16 +296,6 @@ public final class Looper { return mQueue; } - /** - * Return whether this looper's thread is currently idle, waiting for new work - * to do. This is intrinsically racy, since its state can change before you get - * the result back. - * @hide - */ - public boolean isIdling() { - return mQueue.isIdling(); - } - public void dump(Printer pw, String prefix) { pw.println(prefix + toString()); mQueue.dump(pw, prefix + " "); diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index 01a23ce..f4d609c 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -52,21 +52,43 @@ public final class MessageQueue { private native static void nativeDestroy(long ptr); private native static void nativePollOnce(long ptr, int timeoutMillis); private native static void nativeWake(long ptr); - private native static boolean nativeIsIdling(long ptr); + private native static boolean nativeIsPolling(long ptr); + + MessageQueue(boolean quitAllowed) { + mQuitAllowed = quitAllowed; + mPtr = nativeInit(); + } + + @Override + protected void finalize() throws Throwable { + try { + dispose(); + } finally { + super.finalize(); + } + } + + // Disposes of the underlying message queue. + // Must only be called on the looper thread or the finalizer. + private void dispose() { + if (mPtr != 0) { + nativeDestroy(mPtr); + mPtr = 0; + } + } /** - * Callback interface for discovering when a thread is going to block - * waiting for more messages. + * Returns true if the looper has no pending messages which are due to be processed. + * + * <p>This method is safe to call from any thread. + * + * @return True if the looper is idle. */ - public static interface IdleHandler { - /** - * Called when the message queue has run out of messages and will now - * wait for more. Return true to keep your idle handler active, false - * to have it removed. This may be called if there are still messages - * pending in the queue, but they are all scheduled to be dispatched - * after the current time. - */ - boolean queueIdle(); + public boolean isIdle() { + synchronized (this) { + final long now = SystemClock.uptimeMillis(); + return mMessages == null || now < mMessages.when; + } } /** @@ -74,9 +96,9 @@ public final class MessageQueue { * removed automatically for you by returning false from * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is * invoked, or explicitly removing it with {@link #removeIdleHandler}. - * + * * <p>This method is safe to call from any thread. - * + * * @param handler The IdleHandler to be added. */ public void addIdleHandler(IdleHandler handler) { @@ -92,7 +114,9 @@ public final class MessageQueue { * Remove an {@link IdleHandler} from the queue that was previously added * with {@link #addIdleHandler}. If the given object is not currently * in the idle list, nothing is done. - * + * + * <p>This method is safe to call from any thread. + * * @param handler The IdleHandler to be removed. */ public void removeIdleHandler(IdleHandler handler) { @@ -101,27 +125,27 @@ public final class MessageQueue { } } - MessageQueue(boolean quitAllowed) { - mQuitAllowed = quitAllowed; - mPtr = nativeInit(); - } - - @Override - protected void finalize() throws Throwable { - try { - dispose(); - } finally { - super.finalize(); + /** + * Returns whether this looper's thread is currently polling for more work to do. + * This is a good signal that the loop is still alive rather than being stuck + * handling a callback. Note that this method is intrinsically racy, since the + * state of the loop can change before you get the result back. + * + * <p>This method is safe to call from any thread. + * + * @return True if the looper is currently polling for events. + * @hide + */ + public boolean isPolling() { + synchronized (this) { + return isPollingLocked(); } } - // Disposes of the underlying message queue. - // Must only be called on the looper thread or the finalizer. - private void dispose() { - if (mPtr != 0) { - nativeDestroy(mPtr); - mPtr = 0; - } + private boolean isPollingLocked() { + // If the loop is quitting then it must not be idling. + // We can assume mPtr != 0 when mQuitting is false. + return !mQuitting && nativeIsPolling(mPtr); } Message next() { @@ -400,18 +424,6 @@ public final class MessageQueue { } } - boolean isIdling() { - synchronized (this) { - return isIdlingLocked(); - } - } - - private boolean isIdlingLocked() { - // If the loop is quitting then it must not be idling. - // We can assume mPtr != 0 when mQuitting is false. - return !mQuitting && nativeIsIdling(mPtr); - } - void removeMessages(Handler h, int what, Object object) { if (h == null) { return; @@ -559,8 +571,23 @@ public final class MessageQueue { pw.println(prefix + "Message " + n + ": " + msg.toString(now)); n++; } - pw.println(prefix + "(Total messages: " + n + ", idling=" + isIdlingLocked() + pw.println(prefix + "(Total messages: " + n + ", polling=" + isPollingLocked() + ", quitting=" + mQuitting + ")"); } } + + /** + * Callback interface for discovering when a thread is going to block + * waiting for more messages. + */ + public static interface IdleHandler { + /** + * Called when the message queue has run out of messages and will now + * wait for more. Return true to keep your idle handler active, false + * to have it removed. This may be called if there are still messages + * pending in the queue, but they are all scheduled to be dispatched + * after the current time. + */ + boolean queueIdle(); + } } diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp index 5d7877b..ee64044 100644 --- a/core/jni/android_os_MessageQueue.cpp +++ b/core/jni/android_os_MessageQueue.cpp @@ -143,9 +143,9 @@ static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong return nativeMessageQueue->wake(); } -static jboolean android_os_MessageQueue_nativeIsIdling(JNIEnv* env, jclass clazz, jlong ptr) { +static jboolean android_os_MessageQueue_nativeIsPolling(JNIEnv* env, jclass clazz, jlong ptr) { NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr); - return nativeMessageQueue->getLooper()->isIdling(); + return nativeMessageQueue->getLooper()->isPolling(); } // ---------------------------------------------------------------------------- @@ -156,7 +156,7 @@ static JNINativeMethod gMessageQueueMethods[] = { { "nativeDestroy", "(J)V", (void*)android_os_MessageQueue_nativeDestroy }, { "nativePollOnce", "(JI)V", (void*)android_os_MessageQueue_nativePollOnce }, { "nativeWake", "(J)V", (void*)android_os_MessageQueue_nativeWake }, - { "nativeIsIdling", "(J)Z", (void*)android_os_MessageQueue_nativeIsIdling } + { "nativeIsPolling", "(J)Z", (void*)android_os_MessageQueue_nativeIsPolling } }; int register_android_os_MessageQueue(JNIEnv* env) { |