19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.os; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brownimport android.annotation.IntDef; 20dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brownimport android.annotation.NonNull; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 225182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brownimport android.util.Printer; 23dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brownimport android.util.SparseArray; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brownimport java.io.FileDescriptor; 26dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brownimport java.lang.annotation.Retention; 27dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brownimport java.lang.annotation.RetentionPolicy; 2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.util.ArrayList; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Low-level class holding the list of messages to be dispatched by a 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Looper}. Messages are not added directly to a MessageQueue, 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but rather through {@link Handler} objects associated with the Looper. 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>You can retrieve the MessageQueue for the current thread with 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Looper#myQueue() Looper.myQueue()}. 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3867fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brownpublic final class MessageQueue { 39dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown private static final String TAG = "MessageQueue"; 40dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown private static final boolean DEBUG = false; 41dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 420f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // True if the message queue can be quit. 430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private final boolean mQuitAllowed; 440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 450f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown @SuppressWarnings("unused") 4663a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private long mPtr; // used by native code 470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message mMessages; 4946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>(); 50dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown private SparseArray<FileDescriptorRecord> mFileDescriptorRecords; 51ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown private IdleHandler[] mPendingIdleHandlers; 52013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown private boolean mQuitting; 53fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 54415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout. 55415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown private boolean mBlocked; 56415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 570f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // The next barrier token. 580f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Barriers are indicated by messages with a null target whose arg1 field carries the token. 590f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private int mNextBarrierToken; 60e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown 6163a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private native static long nativeInit(); 6263a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private native static void nativeDestroy(long ptr); 63dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/ 6463a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private native static void nativeWake(long ptr); 656c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown private native static boolean nativeIsPolling(long ptr); 66dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events); 676c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown 686c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown MessageQueue(boolean quitAllowed) { 696c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown mQuitAllowed = quitAllowed; 706c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown mPtr = nativeInit(); 716c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown } 726c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown 736c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown @Override 746c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown protected void finalize() throws Throwable { 756c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown try { 766c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown dispose(); 776c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown } finally { 786c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown super.finalize(); 796c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown } 806c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown } 816c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown 826c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown // Disposes of the underlying message queue. 836c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown // Must only be called on the looper thread or the finalizer. 846c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown private void dispose() { 856c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown if (mPtr != 0) { 866c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown nativeDestroy(mPtr); 876c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown mPtr = 0; 886c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown } 896c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown } 9046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 926c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * Returns true if the looper has no pending messages which are due to be processed. 936c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * 946c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * <p>This method is safe to call from any thread. 956c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * 966c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * @return True if the looper is idle. 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 986c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown public boolean isIdle() { 996c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown synchronized (this) { 1006c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown final long now = SystemClock.uptimeMillis(); 1016c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown return mMessages == null || now < mMessages.when; 1026c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Add a new {@link IdleHandler} to this message queue. This may be 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * removed automatically for you by returning false from 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invoked, or explicitly removing it with {@link #removeIdleHandler}. 1106c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This method is safe to call from any thread. 1126c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param handler The IdleHandler to be added. 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 115dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public void addIdleHandler(@NonNull IdleHandler handler) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (handler == null) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new NullPointerException("Can't add a null IdleHandler"); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIdleHandlers.add(handler); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove an {@link IdleHandler} from the queue that was previously added 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with {@link #addIdleHandler}. If the given object is not currently 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the idle list, nothing is done. 1286c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * 1296c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * <p>This method is safe to call from any thread. 1306c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param handler The IdleHandler to be removed. 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 133dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public void removeIdleHandler(@NonNull IdleHandler handler) { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIdleHandlers.remove(handler); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 138e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown 1396c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown /** 1406c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * Returns whether this looper's thread is currently polling for more work to do. 1416c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * This is a good signal that the loop is still alive rather than being stuck 1426c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * handling a callback. Note that this method is intrinsically racy, since the 1436c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * state of the loop can change before you get the result back. 1446c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * 1456c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * <p>This method is safe to call from any thread. 1466c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * 1476c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * @return True if the looper is currently polling for events. 1486c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * @hide 1496c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown */ 1506c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown public boolean isPolling() { 1516c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown synchronized (this) { 1526c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown return isPollingLocked(); 15346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 15446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1566c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown private boolean isPollingLocked() { 1576c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown // If the loop is quitting then it must not be idling. 1586c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown // We can assume mPtr != 0 when mQuitting is false. 1596c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown return !mQuitting && nativeIsPolling(mPtr); 160864693461b6223a995038847591b17abe2de647eJeff Brown } 161864693461b6223a995038847591b17abe2de647eJeff Brown 162dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown /** 1633f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * Adds a file descriptor listener to receive notification when file descriptor 164dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * related events occur. 165dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * <p> 166dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * If the file descriptor has already been registered, the specified events 1673f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * and listener will replace any that were previously associated with it. 1683f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * It is not possible to set more than one listener per file descriptor. 169dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p><p> 1703f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * It is important to always unregister the listener when the file descriptor 171dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * is no longer of use. 172dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p> 173dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * 1743f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * @param fd The file descriptor for which a listener will be registered. 175dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * @param events The set of events to receive: a combination of the 1763f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * {@link OnFileDescriptorEventListener#EVENT_INPUT}, 1773f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * {@link OnFileDescriptorEventListener#EVENT_OUTPUT}, and 1783f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * {@link OnFileDescriptorEventListener#EVENT_ERROR} event masks. If the requested 1793f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * set of events is zero, then the listener is unregistered. 1803f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * @param listener The listener to invoke when file descriptor events occur. 181dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * 1823f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * @see OnFileDescriptorEventListener 1833f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * @see #removeOnFileDescriptorEventListener 184dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown */ 1853f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd, 1863f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown @OnFileDescriptorEventListener.Events int events, 1873f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown @NonNull OnFileDescriptorEventListener listener) { 188dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (fd == null) { 189dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown throw new IllegalArgumentException("fd must not be null"); 190dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 1913f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown if (listener == null) { 1923f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown throw new IllegalArgumentException("listener must not be null"); 193dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 194dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 195dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown synchronized (this) { 1963f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown updateOnFileDescriptorEventListenerLocked(fd, events, listener); 197dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 198dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 199dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 200dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown /** 2013f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * Removes a file descriptor listener. 202dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * <p> 2033f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * This method does nothing if no listener has been registered for the 204dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * specified file descriptor. 205dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p> 206dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * 2073f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * @param fd The file descriptor whose listener will be unregistered. 208dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * 2093f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * @see OnFileDescriptorEventListener 2103f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * @see #addOnFileDescriptorEventListener 211dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown */ 2123f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) { 213dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (fd == null) { 214dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown throw new IllegalArgumentException("fd must not be null"); 215dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 216dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 217dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown synchronized (this) { 2183f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown updateOnFileDescriptorEventListenerLocked(fd, 0, null); 219dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 220dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 221dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 2223f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events, 2233f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown OnFileDescriptorEventListener listener) { 224dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown final int fdNum = fd.getInt$(); 225dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 226dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown int index = -1; 227dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown FileDescriptorRecord record = null; 228dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (mFileDescriptorRecords != null) { 229dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown index = mFileDescriptorRecords.indexOfKey(fdNum); 230dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (index >= 0) { 231dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown record = mFileDescriptorRecords.valueAt(index); 232dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (record != null && record.mEvents == events) { 233dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown return; 234dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 235dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 236dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 237dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 238dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (events != 0) { 2393f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown events |= OnFileDescriptorEventListener.EVENT_ERROR; 240dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (record == null) { 241dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (mFileDescriptorRecords == null) { 242dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>(); 243dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 2443f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown record = new FileDescriptorRecord(fd, events, listener); 245dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown mFileDescriptorRecords.put(fdNum, record); 246dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } else { 2473f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown record.mListener = listener; 248dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown record.mEvents = events; 249dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown record.mSeq += 1; 250dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 251dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown nativeSetFileDescriptorEvents(mPtr, fdNum, events); 252dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } else if (record != null) { 253dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown record.mEvents = 0; 254dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown mFileDescriptorRecords.removeAt(index); 255dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 256dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 257dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 258dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown // Called from native code. 259dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown private int dispatchEvents(int fd, int events) { 260dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown // Get the file descriptor record and any state that might change. 261dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown final FileDescriptorRecord record; 262dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown final int oldWatchedEvents; 2633f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown final OnFileDescriptorEventListener listener; 264dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown final int seq; 265dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown synchronized (this) { 266dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown record = mFileDescriptorRecords.get(fd); 267dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (record == null) { 2683f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown return 0; // spurious, no listener registered 269dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 270dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 271dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown oldWatchedEvents = record.mEvents; 272dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown events &= oldWatchedEvents; // filter events based on current watched set 273dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (events == 0) { 274dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown return oldWatchedEvents; // spurious, watched events changed 275dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 276dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 2773f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown listener = record.mListener; 278dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown seq = record.mSeq; 279dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 280dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 2813f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown // Invoke the listener outside of the lock. 2823f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown int newWatchedEvents = listener.onFileDescriptorEvents( 283dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown record.mDescriptor, events); 284dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (newWatchedEvents != 0) { 2853f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR; 286dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 287dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 2883f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown // Update the file descriptor record if the listener changed the set of 2893f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown // events to watch and the listener itself hasn't been updated since. 290dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (newWatchedEvents != oldWatchedEvents) { 291dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown synchronized (this) { 292dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown int index = mFileDescriptorRecords.indexOfKey(fd); 293dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record 294dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown && record.mSeq == seq) { 295dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown record.mEvents = newWatchedEvents; 296dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (newWatchedEvents == 0) { 297dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown mFileDescriptorRecords.removeAt(index); 298dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 299dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 300dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 301dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 302dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 303dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown // Return the new set of events to watch for native code to take care of. 304dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown return newWatchedEvents; 305dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 306dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 30767fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown Message next() { 308605839066af9a5825c074e54e3db90cf88a2220aJeff Brown // Return here if the message loop has already quit and been disposed. 309605839066af9a5825c074e54e3db90cf88a2220aJeff Brown // This can happen if the application tries to restart a looper after quit 310605839066af9a5825c074e54e3db90cf88a2220aJeff Brown // which is not supported. 311ab8643452adcf91781991bce03be26f072311d89Narayan Kamath final long ptr = mPtr; 312605839066af9a5825c074e54e3db90cf88a2220aJeff Brown if (ptr == 0) { 313605839066af9a5825c074e54e3db90cf88a2220aJeff Brown return null; 314605839066af9a5825c074e54e3db90cf88a2220aJeff Brown } 315605839066af9a5825c074e54e3db90cf88a2220aJeff Brown 316ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown int pendingIdleHandlerCount = -1; // -1 only during first iteration 317ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown int nextPollTimeoutMillis = 0; 318ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown for (;;) { 319ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown if (nextPollTimeoutMillis != 0) { 320ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown Binder.flushPendingCommands(); 321ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 322013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown 323605839066af9a5825c074e54e3db90cf88a2220aJeff Brown nativePollOnce(ptr, nextPollTimeoutMillis); 324fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 326ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // Try to retrieve the next message. Return if found. 327ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown final long now = SystemClock.uptimeMillis(); 328e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown Message prevMsg = null; 329e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown Message msg = mMessages; 3300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg != null && msg.target == null) { 3310f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Stalled by a barrier. Find the next asynchronous message in the queue. 3320f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown do { 3330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prevMsg = msg; 3340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg = msg.next; 3350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } while (msg != null && !msg.isAsynchronous()); 3360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg != null) { 3380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (now < msg.when) { 339e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // Next message is not ready. Set a timeout to wake up when it is ready. 3400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); 3410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 342e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // Got a message. 343415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mBlocked = false; 344e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown if (prevMsg != null) { 345e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown prevMsg.next = msg.next; 346e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown } else { 347e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown mMessages = msg.next; 348e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown } 349415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown msg.next = null; 350dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown if (DEBUG) Log.v(TAG, "Returning message: " + msg); 351dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown msg.markInUse(); 352ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown return msg; 353ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 3540f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 3550f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // No more messages. 3560f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown nextPollTimeoutMillis = -1; 35746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 358ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown 359024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown // Process the quit message now that all pending messages have been handled. 360013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (mQuitting) { 361024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown dispose(); 362024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown return null; 363024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown } 364024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown 365e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // If first time idle, then get the number of idlers to run. 3660f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Idle handles only run if the queue is empty or if the first message 3670f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // in the queue (possibly a barrier) is due to be handled in the future. 3680f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (pendingIdleHandlerCount < 0 3690f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown && (mMessages == null || now < mMessages.when)) { 370ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown pendingIdleHandlerCount = mIdleHandlers.size(); 371ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 372e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown if (pendingIdleHandlerCount <= 0) { 373ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // No idle handlers to run. Loop and wait some more. 374415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mBlocked = true; 375ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown continue; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 378ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown if (mPendingIdleHandlers == null) { 379ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 381ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 384ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // Run the idle handlers. 385ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // We only ever reach this code block during the first iteration. 386ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown for (int i = 0; i < pendingIdleHandlerCount; i++) { 387ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown final IdleHandler idler = mPendingIdleHandlers[i]; 388ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mPendingIdleHandlers[i] = null; // release the reference to the handler 389ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown 390ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown boolean keep = false; 391ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown try { 392ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown keep = idler.queueIdle(); 393ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } catch (Throwable t) { 394dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown Log.wtf(TAG, "IdleHandler threw exception", t); 395ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 396ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown 397ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown if (!keep) { 398ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown synchronized (this) { 399ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mIdleHandlers.remove(idler); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 404ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // Reset the idle handler count to 0 so we do not run them again. 405ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown pendingIdleHandlerCount = 0; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 407ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // While calling an idle handler, a new message could have been delivered 408ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // so go back and look again for a pending message without waiting. 409ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown nextPollTimeoutMillis = 0; 410ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4138b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown void quit(boolean safe) { 4140f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (!mQuitAllowed) { 4159867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown throw new IllegalStateException("Main thread not allowed to quit."); 4160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 4180f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 419013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (mQuitting) { 4200f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 4210f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 422013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown mQuitting = true; 4238b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 4248b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (safe) { 4258b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown removeAllFutureMessagesLocked(); 4268b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } else { 4278b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown removeAllMessagesLocked(); 4288b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 429013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown 430013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // We can assume mPtr != 0 because mQuitting was previously false. 431013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown nativeWake(mPtr); 4320f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 4353d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown /** 4363d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * Posts a synchronization barrier to the Looper's message queue. 4373d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * 4383d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * Message processing occurs as usual until the message queue encounters the 4393d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * synchronization barrier that has been posted. When the barrier is encountered, 4403d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * later synchronous messages in the queue are stalled (prevented from being executed) 4413d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * until the barrier is released by calling {@link #removeSyncBarrier} and specifying 4423d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * the token that identifies the synchronization barrier. 4433d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * 4443d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * This method is used to immediately postpone execution of all subsequently posted 4453d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * synchronous messages until a condition is met that releases the barrier. 4463d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier 4473d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * and continue to be processed as usual. 4483d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * 4493d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * This call must be always matched by a call to {@link #removeSyncBarrier} with 4503d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * the same token to ensure that the message queue resumes normal operation. 4513d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * Otherwise the application will probably hang! 4523d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * 4533d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * @return A token that uniquely identifies the barrier. This token must be 4543d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * passed to {@link #removeSyncBarrier} to release the barrier. 4553d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * 4563d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * @hide 4573d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown */ 4583d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown public int postSyncBarrier() { 4593d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown return postSyncBarrier(SystemClock.uptimeMillis()); 4603d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown } 4613d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown 4623d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown private int postSyncBarrier(long when) { 4630f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Enqueue a new sync barrier token. 4640f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // We don't need to wake the queue because the purpose of a barrier is to stall it. 4650f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 4660f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final int token = mNextBarrierToken++; 4670f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final Message msg = Message.obtain(); 4689867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown msg.markInUse(); 4695182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown msg.when = when; 4700f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.arg1 = token; 4710f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 4720f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message prev = null; 4730f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message p = mMessages; 4740f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (when != 0) { 4750f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown while (p != null && p.when <= when) { 4760f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev = p; 4770f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p = p.next; 4780f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4790f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4800f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (prev != null) { // invariant: p == prev.next 4810f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.next = p; 4820f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev.next = msg; 4830f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 4840f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.next = p; 4850f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mMessages = msg; 4860f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4870f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return token; 4880f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4890f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4900f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 4913d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown /** 4923d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * Removes a synchronization barrier. 4933d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * 4943d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * @param token The synchronization barrier token that was returned by 4953d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * {@link #postSyncBarrier}. 4963d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * 4973d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * @throws IllegalStateException if the barrier was not found. 4983d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * 4993d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown * @hide 5003d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown */ 5013d4e7efe37a4b0dfc5807444e8c3b98a28953377Jeff Brown public void removeSyncBarrier(int token) { 5020f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Remove a sync barrier token from the queue. 5030f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // If the queue is no longer stalled by a barrier then wake it. 5040f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 5050f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message prev = null; 5060f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message p = mMessages; 5070f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown while (p != null && (p.target != null || p.arg1 != token)) { 5080f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev = p; 5090f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p = p.next; 5100f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 5110f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (p == null) { 5120f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown throw new IllegalStateException("The specified message queue synchronization " 5130f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + " barrier token has not been posted or has already been removed."); 5140f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 515013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown final boolean needWake; 5160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (prev != null) { 5170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev.next = p.next; 5180f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = false; 5190f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 5200f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mMessages = p.next; 5210f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = mMessages == null || mMessages.target != null; 5220f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 5239867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 524013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown 525013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // If the loop is quitting then it is already awake. 526013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // We can assume mPtr != 0 when mQuitting is false. 527013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (needWake && !mQuitting) { 528013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown nativeWake(mPtr); 529013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown } 5300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 5310f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 5320f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 53367fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown boolean enqueueMessage(Message msg, long when) { 5340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg.target == null) { 5359867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown throw new IllegalArgumentException("Message must have a target."); 5369867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown } 5379867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown if (msg.isInUse()) { 5389867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown throw new IllegalStateException(msg + " This message is already in use."); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 542013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (mQuitting) { 5439867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown IllegalStateException e = new IllegalStateException( 5440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.target + " sending message to a Handler on a dead thread"); 545dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown Log.w(TAG, e.getMessage(), e); 5469867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown msg.recycle(); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown msg.markInUse(); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.when = when; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 553013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown boolean needWake; 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null || when == 0 || when < p.when) { 555e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // New head, wake up the event queue if blocked. 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.next = p; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = msg; 558e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown needWake = mBlocked; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 560e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // Inserted within the middle of the queue. Usually we don't have to wake 5610f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // up the event queue unless there is a barrier at the head of the queue 5620f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // and the message is the earliest asynchronous message in the queue. 5630f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = mBlocked && p.target == null && msg.isAsynchronous(); 5640f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message prev; 5650f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown for (;;) { 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prev = p; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = p.next; 5680f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (p == null || when < p.when) { 5690f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown break; 5700f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 5710f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (needWake && p.isAsynchronous()) { 5720f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = false; 5730f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5750f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.next = p; // invariant: p == prev.next 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prev.next = msg; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 578013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown 579013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // We can assume mPtr != 0 because mQuitting is false. 580013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (needWake) { 581013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown nativeWake(mPtr); 582013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown } 583415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 58767fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown boolean hasMessages(Handler h, int what, Object object) { 5880f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null) { 5890f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return false; 5900f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 5910f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 5920f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 5930f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message p = mMessages; 5940f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown while (p != null) { 5950f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (p.target == h && p.what == what && (object == null || p.obj == object)) { 5960f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return true; 5970f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 5980f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p = p.next; 599ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 600ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy return false; 601ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 602ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 603ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 60467fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown boolean hasMessages(Handler h, Runnable r, Object object) { 605ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy if (h == null) { 606ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy return false; 607ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 608ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 609ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy synchronized (this) { 610ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy Message p = mMessages; 611ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy while (p != null) { 612ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy if (p.target == h && p.callback == r && (object == null || p.obj == object)) { 613ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy return true; 614ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 615ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy p = p.next; 6160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 6170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return false; 6180f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 6190f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 6200f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 62167fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown void removeMessages(Handler h, int what, Object object) { 6220f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null) { 6230f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 6240f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 6250f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages at front. 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null && p.target == h && p.what == what 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || p.obj == object)) { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = n; 6349867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages after front. 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null) { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != null) { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n.target == h && n.what == what 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || n.obj == object)) { 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message nn = n.next; 6459867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown n.recycleUnchecked(); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.next = nn; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 65567fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown void removeMessages(Handler h, Runnable r, Object object) { 6560f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null || r == null) { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages at front. 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null && p.target == h && p.callback == r 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || p.obj == object)) { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = n; 6689867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages after front. 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null) { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != null) { 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n.target == h && n.callback == r 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || n.obj == object)) { 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message nn = n.next; 6799867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown n.recycleUnchecked(); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.next = nn; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 68967fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown void removeCallbacksAndMessages(Handler h, Object object) { 6900f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null) { 6910f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 6920f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 6930f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages at front. 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null && p.target == h 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || p.obj == object)) { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = n; 7029867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages after front. 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null) { 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != null) { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n.target == h && (object == null || n.obj == object)) { 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message nn = n.next; 7129867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown n.recycleUnchecked(); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.next = nn; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7218b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 7228b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown private void removeAllMessagesLocked() { 7238b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Message p = mMessages; 7248b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown while (p != null) { 7258b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Message n = p.next; 7269867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 7278b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown p = n; 7288b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 7298b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown mMessages = null; 7308b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 7318b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 7328b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown private void removeAllFutureMessagesLocked() { 7338b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown final long now = SystemClock.uptimeMillis(); 7348b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Message p = mMessages; 7358b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (p != null) { 7368b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (p.when > now) { 7378b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown removeAllMessagesLocked(); 7388b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } else { 7398b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Message n; 7408b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown for (;;) { 7418b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown n = p.next; 7428b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (n == null) { 7438b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown return; 7448b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 7458b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (n.when > now) { 7468b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown break; 7478b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 7488b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown p = n; 7498b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 7508b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown p.next = null; 7518b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown do { 7528b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown p = n; 7538b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown n = p.next; 7549867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 7558b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } while (n != null); 7568b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 7578b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 7588b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 7595182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown 7605182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown void dump(Printer pw, String prefix) { 7615182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown synchronized (this) { 7625182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown long now = SystemClock.uptimeMillis(); 7635182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown int n = 0; 7645182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown for (Message msg = mMessages; msg != null; msg = msg.next) { 7655182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown pw.println(prefix + "Message " + n + ": " + msg.toString(now)); 7665182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown n++; 7675182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown } 7686c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown pw.println(prefix + "(Total messages: " + n + ", polling=" + isPollingLocked() 7695182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown + ", quitting=" + mQuitting + ")"); 7705182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown } 7715182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown } 7726c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown 7736c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown /** 7746c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * Callback interface for discovering when a thread is going to block 7756c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * waiting for more messages. 7766c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown */ 7776c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown public static interface IdleHandler { 7786c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown /** 7796c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * Called when the message queue has run out of messages and will now 7806c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * wait for more. Return true to keep your idle handler active, false 7816c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * to have it removed. This may be called if there are still messages 7826c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * pending in the queue, but they are all scheduled to be dispatched 7836c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown * after the current time. 7846c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown */ 7856c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown boolean queueIdle(); 7866c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown } 787dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 788dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown /** 7893f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * A listener which is invoked when file descriptor related events occur. 790dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown */ 7913f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown public interface OnFileDescriptorEventListener { 792dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown /** 793dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * File descriptor event: Indicates that the file descriptor is ready for input 794dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * operations, such as reading. 795dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * <p> 7963f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * The listener should read all available data from the file descriptor 7973f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * then return <code>true</code> to keep the listener active or <code>false</code> 7983f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * to remove the listener. 799dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p><p> 800dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * In the case of a socket, this event may be generated to indicate 8013f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * that there is at least one incoming connection that the listener 802dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * should accept. 803dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p><p> 804dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * This event will only be generated if the {@link #EVENT_INPUT} event mask was 8053f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * specified when the listener was added. 806dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p> 807dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown */ 808dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public static final int EVENT_INPUT = 1 << 0; 809dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 810dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown /** 811dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * File descriptor event: Indicates that the file descriptor is ready for output 812dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * operations, such as writing. 813dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * <p> 8143f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * The listener should write as much data as it needs. If it could not 815dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * write everything at once, then it should return <code>true</code> to 8163f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * keep the listener active. Otherwise, it should return <code>false</code> 8173f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * to remove the listener then re-register it later when it needs to write 818dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * something else. 819dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p><p> 820dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * This event will only be generated if the {@link #EVENT_OUTPUT} event mask was 8213f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * specified when the listener was added. 822dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p> 823dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown */ 824dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public static final int EVENT_OUTPUT = 1 << 1; 825dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 826dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown /** 827dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * File descriptor event: Indicates that the file descriptor encountered a 828dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * fatal error. 829dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * <p> 830dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * File descriptor errors can occur for various reasons. One common error 831dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * is when the remote peer of a socket or pipe closes its end of the connection. 832dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p><p> 833dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * This event may be generated at any time regardless of whether the 8343f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * {@link #EVENT_ERROR} event mask was specified when the listener was added. 835dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * </p> 836dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown */ 837dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public static final int EVENT_ERROR = 1 << 2; 838dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 839dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown /** @hide */ 840dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown @Retention(RetentionPolicy.SOURCE) 841dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown @IntDef(flag=true, value={EVENT_INPUT, EVENT_OUTPUT, EVENT_ERROR}) 842dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public @interface Events {} 843dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 844dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown /** 845dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * Called when a file descriptor receives events. 846dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * 847dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * @param fd The file descriptor. 848dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * @param events The set of events that occurred: a combination of the 849dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * {@link #EVENT_INPUT}, {@link #EVENT_OUTPUT}, and {@link #EVENT_ERROR} event masks. 8503f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown * @return The new set of events to watch, or 0 to unregister the listener. 851dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * 852dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * @see #EVENT_INPUT 853dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * @see #EVENT_OUTPUT 854dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown * @see #EVENT_ERROR 855dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown */ 8563f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown @Events int onFileDescriptorEvents(@NonNull FileDescriptor fd, @Events int events); 857dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 858dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 859dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown private static final class FileDescriptorRecord { 860dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public final FileDescriptor mDescriptor; 861dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public int mEvents; 8623f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown public OnFileDescriptorEventListener mListener; 863dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public int mSeq; 864dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown 865dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown public FileDescriptorRecord(FileDescriptor descriptor, 8663f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown int events, OnFileDescriptorEventListener listener) { 867dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown mDescriptor = descriptor; 868dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown mEvents = events; 8693f6405259aab3d9d5bd0a1f6dec98ad27e774f69Jeff Brown mListener = listener; 870dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 871dc3eb4bf91d37ce6b8b000a59625a496b64b36fbJeff Brown } 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 873