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 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 205182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brownimport android.util.Printer; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.util.ArrayList; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Low-level class holding the list of messages to be dispatched by a 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Looper}. Messages are not added directly to a MessageQueue, 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but rather through {@link Handler} objects associated with the Looper. 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>You can retrieve the MessageQueue for the current thread with 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Looper#myQueue() Looper.myQueue()}. 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3267fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brownpublic final class MessageQueue { 330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // True if the message queue can be quit. 340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private final boolean mQuitAllowed; 350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown @SuppressWarnings("unused") 3763a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private long mPtr; // used by native code 380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message mMessages; 4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>(); 41ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown private IdleHandler[] mPendingIdleHandlers; 42013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown private boolean mQuitting; 43fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 44415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout. 45415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown private boolean mBlocked; 46415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // The next barrier token. 480f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Barriers are indicated by messages with a null target whose arg1 field carries the token. 490f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private int mNextBarrierToken; 50e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown 5163a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private native static long nativeInit(); 5263a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private native static void nativeDestroy(long ptr); 5363a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private native static void nativePollOnce(long ptr, int timeoutMillis); 5463a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private native static void nativeWake(long ptr); 5563a37153238d95cf8897939e6d6e8fbc56e9ec7fAshok Bhat private native static boolean nativeIsIdling(long ptr); 5646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback interface for discovering when a thread is going to block 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * waiting for more messages. 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static interface IdleHandler { 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when the message queue has run out of messages and will now 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * wait for more. Return true to keep your idle handler active, false 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to have it removed. This may be called if there are still messages 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pending in the queue, but they are all scheduled to be dispatched 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * after the current time. 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean queueIdle(); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Add a new {@link IdleHandler} to this message queue. This may be 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * removed automatically for you by returning false from 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invoked, or explicitly removing it with {@link #removeIdleHandler}. 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This method is safe to call from any thread. 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param handler The IdleHandler to be added. 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8267fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown public void addIdleHandler(IdleHandler handler) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (handler == null) { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new NullPointerException("Can't add a null IdleHandler"); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIdleHandlers.add(handler); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove an {@link IdleHandler} from the queue that was previously added 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with {@link #addIdleHandler}. If the given object is not currently 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the idle list, nothing is done. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param handler The IdleHandler to be removed. 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9867fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown public void removeIdleHandler(IdleHandler handler) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIdleHandlers.remove(handler); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 103e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown 1040f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown MessageQueue(boolean quitAllowed) { 1050f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mQuitAllowed = quitAllowed; 106864693461b6223a995038847591b17abe2de647eJeff Brown mPtr = nativeInit(); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1080f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 10946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown @Override 11046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown protected void finalize() throws Throwable { 11146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown try { 112864693461b6223a995038847591b17abe2de647eJeff Brown dispose(); 11346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } finally { 11446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown super.finalize(); 11546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 11646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 118013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // Disposes of the underlying message queue. 119013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // Must only be called on the looper thread or the finalizer. 120864693461b6223a995038847591b17abe2de647eJeff Brown private void dispose() { 121864693461b6223a995038847591b17abe2de647eJeff Brown if (mPtr != 0) { 122864693461b6223a995038847591b17abe2de647eJeff Brown nativeDestroy(mPtr); 123864693461b6223a995038847591b17abe2de647eJeff Brown mPtr = 0; 124864693461b6223a995038847591b17abe2de647eJeff Brown } 125864693461b6223a995038847591b17abe2de647eJeff Brown } 126864693461b6223a995038847591b17abe2de647eJeff Brown 12767fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown Message next() { 128605839066af9a5825c074e54e3db90cf88a2220aJeff Brown // Return here if the message loop has already quit and been disposed. 129605839066af9a5825c074e54e3db90cf88a2220aJeff Brown // This can happen if the application tries to restart a looper after quit 130605839066af9a5825c074e54e3db90cf88a2220aJeff Brown // which is not supported. 131ab8643452adcf91781991bce03be26f072311d89Narayan Kamath final long ptr = mPtr; 132605839066af9a5825c074e54e3db90cf88a2220aJeff Brown if (ptr == 0) { 133605839066af9a5825c074e54e3db90cf88a2220aJeff Brown return null; 134605839066af9a5825c074e54e3db90cf88a2220aJeff Brown } 135605839066af9a5825c074e54e3db90cf88a2220aJeff Brown 136ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown int pendingIdleHandlerCount = -1; // -1 only during first iteration 137ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown int nextPollTimeoutMillis = 0; 138ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown for (;;) { 139ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown if (nextPollTimeoutMillis != 0) { 140ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown Binder.flushPendingCommands(); 141ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 142013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown 143605839066af9a5825c074e54e3db90cf88a2220aJeff Brown nativePollOnce(ptr, nextPollTimeoutMillis); 144fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 146ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // Try to retrieve the next message. Return if found. 147ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown final long now = SystemClock.uptimeMillis(); 148e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown Message prevMsg = null; 149e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown Message msg = mMessages; 1500f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg != null && msg.target == null) { 1510f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Stalled by a barrier. Find the next asynchronous message in the queue. 1520f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown do { 1530f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prevMsg = msg; 1540f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg = msg.next; 1550f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } while (msg != null && !msg.isAsynchronous()); 1560f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 1570f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg != null) { 1580f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (now < msg.when) { 159e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // Next message is not ready. Set a timeout to wake up when it is ready. 1600f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); 1610f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 162e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // Got a message. 163415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mBlocked = false; 164e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown if (prevMsg != null) { 165e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown prevMsg.next = msg.next; 166e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown } else { 167e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown mMessages = msg.next; 168e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown } 169415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown msg.next = null; 17043a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("MessageQueue", "Returning message: " + msg); 171ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown return msg; 172ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 1730f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 1740f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // No more messages. 1750f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown nextPollTimeoutMillis = -1; 17646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 177ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown 178024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown // Process the quit message now that all pending messages have been handled. 179013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (mQuitting) { 180024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown dispose(); 181024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown return null; 182024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown } 183024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown 184e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // If first time idle, then get the number of idlers to run. 1850f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Idle handles only run if the queue is empty or if the first message 1860f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // in the queue (possibly a barrier) is due to be handled in the future. 1870f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (pendingIdleHandlerCount < 0 1880f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown && (mMessages == null || now < mMessages.when)) { 189ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown pendingIdleHandlerCount = mIdleHandlers.size(); 190ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 191e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown if (pendingIdleHandlerCount <= 0) { 192ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // No idle handlers to run. Loop and wait some more. 193415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mBlocked = true; 194ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown continue; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 197ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown if (mPendingIdleHandlers == null) { 198ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 200ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 203ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // Run the idle handlers. 204ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // We only ever reach this code block during the first iteration. 205ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown for (int i = 0; i < pendingIdleHandlerCount; i++) { 206ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown final IdleHandler idler = mPendingIdleHandlers[i]; 207ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mPendingIdleHandlers[i] = null; // release the reference to the handler 208ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown 209ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown boolean keep = false; 210ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown try { 211ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown keep = idler.queueIdle(); 212ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } catch (Throwable t) { 213ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown Log.wtf("MessageQueue", "IdleHandler threw exception", t); 214ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 215ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown 216ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown if (!keep) { 217ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown synchronized (this) { 218ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mIdleHandlers.remove(idler); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 223ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // Reset the idle handler count to 0 so we do not run them again. 224ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown pendingIdleHandlerCount = 0; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 226ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // While calling an idle handler, a new message could have been delivered 227ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // so go back and look again for a pending message without waiting. 228ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown nextPollTimeoutMillis = 0; 229ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2328b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown void quit(boolean safe) { 2330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (!mQuitAllowed) { 2349867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown throw new IllegalStateException("Main thread not allowed to quit."); 2350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 238013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (mQuitting) { 2390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 2400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 241013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown mQuitting = true; 2428b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 2438b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (safe) { 2448b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown removeAllFutureMessagesLocked(); 2458b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } else { 2468b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown removeAllMessagesLocked(); 2478b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 248013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown 249013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // We can assume mPtr != 0 because mQuitting was previously false. 250013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown nativeWake(mPtr); 2510f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2520f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2530f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 25467fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown int enqueueSyncBarrier(long when) { 2550f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Enqueue a new sync barrier token. 2560f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // We don't need to wake the queue because the purpose of a barrier is to stall it. 2570f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 2580f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final int token = mNextBarrierToken++; 2590f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final Message msg = Message.obtain(); 2609867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown msg.markInUse(); 2615182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown msg.when = when; 2620f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.arg1 = token; 2630f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2640f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message prev = null; 2650f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message p = mMessages; 2660f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (when != 0) { 2670f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown while (p != null && p.when <= when) { 2680f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev = p; 2690f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p = p.next; 2700f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2710f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2720f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (prev != null) { // invariant: p == prev.next 2730f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.next = p; 2740f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev.next = msg; 2750f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 2760f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.next = p; 2770f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mMessages = msg; 2780f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2790f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return token; 2800f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2810f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2820f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 28367fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown void removeSyncBarrier(int token) { 2840f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Remove a sync barrier token from the queue. 2850f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // If the queue is no longer stalled by a barrier then wake it. 2860f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 2870f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message prev = null; 2880f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message p = mMessages; 2890f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown while (p != null && (p.target != null || p.arg1 != token)) { 2900f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev = p; 2910f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p = p.next; 2920f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2930f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (p == null) { 2940f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown throw new IllegalStateException("The specified message queue synchronization " 2950f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + " barrier token has not been posted or has already been removed."); 2960f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 297013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown final boolean needWake; 2980f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (prev != null) { 2990f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev.next = p.next; 3000f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = false; 3010f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 3020f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mMessages = p.next; 3030f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = mMessages == null || mMessages.target != null; 3040f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3059867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 306013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown 307013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // If the loop is quitting then it is already awake. 308013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // We can assume mPtr != 0 when mQuitting is false. 309013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (needWake && !mQuitting) { 310013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown nativeWake(mPtr); 311013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown } 3120f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3130f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3140f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 31567fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown boolean enqueueMessage(Message msg, long when) { 3160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg.target == null) { 3179867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown throw new IllegalArgumentException("Message must have a target."); 3189867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown } 3199867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown if (msg.isInUse()) { 3209867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown throw new IllegalStateException(msg + " This message is already in use."); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3220f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 324013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (mQuitting) { 3259867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown IllegalStateException e = new IllegalStateException( 3260f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.target + " sending message to a Handler on a dead thread"); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("MessageQueue", e.getMessage(), e); 3289867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown msg.recycle(); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown msg.markInUse(); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.when = when; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 335013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown boolean needWake; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null || when == 0 || when < p.when) { 337e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // New head, wake up the event queue if blocked. 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.next = p; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = msg; 340e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown needWake = mBlocked; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 342e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // Inserted within the middle of the queue. Usually we don't have to wake 3430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // up the event queue unless there is a barrier at the head of the queue 3440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // and the message is the earliest asynchronous message in the queue. 3450f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = mBlocked && p.target == null && msg.isAsynchronous(); 3460f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message prev; 3470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown for (;;) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prev = p; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = p.next; 3500f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (p == null || when < p.when) { 3510f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown break; 3520f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3530f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (needWake && p.isAsynchronous()) { 3540f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = false; 3550f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3570f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.next = p; // invariant: p == prev.next 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prev.next = msg; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 360013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown 361013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown // We can assume mPtr != 0 because mQuitting is false. 362013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown if (needWake) { 363013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown nativeWake(mPtr); 364013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown } 365415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36967fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown boolean hasMessages(Handler h, int what, Object object) { 3700f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null) { 3710f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return false; 3720f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3730f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 3740f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 3750f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message p = mMessages; 3760f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown while (p != null) { 3770f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (p.target == h && p.what == what && (object == null || p.obj == object)) { 3780f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return true; 3790f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3800f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p = p.next; 381ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 382ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy return false; 383ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 384ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 385ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 38667fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown boolean hasMessages(Handler h, Runnable r, Object object) { 387ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy if (h == null) { 388ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy return false; 389ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 390ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 391ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy synchronized (this) { 392ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy Message p = mMessages; 393ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy while (p != null) { 394ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy if (p.target == h && p.callback == r && (object == null || p.obj == object)) { 395ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy return true; 396ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 397ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy p = p.next; 3980f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3990f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return false; 4000f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4010f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4020f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 403efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn boolean isIdling() { 404013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown synchronized (this) { 4055182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown return isIdlingLocked(); 406013cf847bcfd2828d34dced60adf2d3dd98021dcJeff Brown } 407efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn } 408efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn 4095182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown private boolean isIdlingLocked() { 4105182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown // If the loop is quitting then it must not be idling. 4115182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown // We can assume mPtr != 0 when mQuitting is false. 4125182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown return !mQuitting && nativeIsIdling(mPtr); 4135182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown } 4145182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown 41567fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown void removeMessages(Handler h, int what, Object object) { 4160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null) { 4170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 4180f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4190f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages at front. 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null && p.target == h && p.what == what 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || p.obj == object)) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = n; 4289867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages after front. 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != null) { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n.target == h && n.what == what 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || n.obj == object)) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message nn = n.next; 4399867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown n.recycleUnchecked(); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.next = nn; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 44967fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown void removeMessages(Handler h, Runnable r, Object object) { 4500f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null || r == null) { 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages at front. 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null && p.target == h && p.callback == r 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || p.obj == object)) { 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = n; 4629867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages after front. 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null) { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != null) { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n.target == h && n.callback == r 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || n.obj == object)) { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message nn = n.next; 4739867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown n.recycleUnchecked(); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.next = nn; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48367fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown void removeCallbacksAndMessages(Handler h, Object object) { 4840f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null) { 4850f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 4860f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4870f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages at front. 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null && p.target == h 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || p.obj == object)) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = n; 4969867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages after front. 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null) { 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != null) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n.target == h && (object == null || n.obj == object)) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message nn = n.next; 5069867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown n.recycleUnchecked(); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.next = nn; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5158b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 5168b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown private void removeAllMessagesLocked() { 5178b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Message p = mMessages; 5188b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown while (p != null) { 5198b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Message n = p.next; 5209867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 5218b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown p = n; 5228b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 5238b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown mMessages = null; 5248b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 5258b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 5268b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown private void removeAllFutureMessagesLocked() { 5278b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown final long now = SystemClock.uptimeMillis(); 5288b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Message p = mMessages; 5298b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (p != null) { 5308b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (p.when > now) { 5318b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown removeAllMessagesLocked(); 5328b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } else { 5338b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown Message n; 5348b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown for (;;) { 5358b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown n = p.next; 5368b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (n == null) { 5378b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown return; 5388b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 5398b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown if (n.when > now) { 5408b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown break; 5418b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 5428b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown p = n; 5438b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 5448b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown p.next = null; 5458b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown do { 5468b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown p = n; 5478b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown n = p.next; 5489867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown p.recycleUnchecked(); 5498b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } while (n != null); 5508b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 5518b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 5528b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 5535182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown 5545182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown void dump(Printer pw, String prefix) { 5555182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown synchronized (this) { 5565182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown long now = SystemClock.uptimeMillis(); 5575182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown int n = 0; 5585182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown for (Message msg = mMessages; msg != null; msg = msg.next) { 5595182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown pw.println(prefix + "Message " + n + ": " + msg.toString(now)); 5605182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown n++; 5615182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown } 5625182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown pw.println(prefix + "(Total messages: " + n + ", idling=" + isIdlingLocked() 5635182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown + ", quitting=" + mQuitting + ")"); 5645182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown } 5655182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 567