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.AndroidRuntimeException; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 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 */ 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class MessageQueue { 330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // True if the message queue can be quit. 340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private final boolean mQuitAllowed; 350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown @SuppressWarnings("unused") 370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private int 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; 42415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown private boolean mQuiting; 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 5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown private native void nativeInit(); 5246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown private native void nativeDestroy(); 53415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown private native void nativePollOnce(int ptr, int timeoutMillis); 54415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown private native void nativeWake(int ptr); 5546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Callback interface for discovering when a thread is going to block 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * waiting for more messages. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static interface IdleHandler { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when the message queue has run out of messages and will now 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * wait for more. Return true to keep your idle handler active, false 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to have it removed. This may be called if there are still messages 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pending in the queue, but they are all scheduled to be dispatched 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * after the current time. 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean queueIdle(); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Add a new {@link IdleHandler} to this message queue. This may be 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * removed automatically for you by returning false from 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invoked, or explicitly removing it with {@link #removeIdleHandler}. 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This method is safe to call from any thread. 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param handler The IdleHandler to be added. 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void addIdleHandler(IdleHandler handler) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (handler == null) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new NullPointerException("Can't add a null IdleHandler"); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIdleHandlers.add(handler); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove an {@link IdleHandler} from the queue that was previously added 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with {@link #addIdleHandler}. If the given object is not currently 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the idle list, nothing is done. 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param handler The IdleHandler to be removed. 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void removeIdleHandler(IdleHandler handler) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIdleHandlers.remove(handler); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 102e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown 1030f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown MessageQueue(boolean quitAllowed) { 1040f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mQuitAllowed = quitAllowed; 105fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate nativeInit(); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1070f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 10846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown @Override 10946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown protected void finalize() throws Throwable { 11046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown try { 11146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nativeDestroy(); 11246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } finally { 11346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown super.finalize(); 11446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 11546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Message next() { 118ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown int pendingIdleHandlerCount = -1; // -1 only during first iteration 119ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown int nextPollTimeoutMillis = 0; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 121ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown for (;;) { 122ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown if (nextPollTimeoutMillis != 0) { 123ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown Binder.flushPendingCommands(); 124ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 125415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown nativePollOnce(mPtr, nextPollTimeoutMillis); 126fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1280f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (mQuiting) { 1290f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return null; 1300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 1310f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 132ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // Try to retrieve the next message. Return if found. 133ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown final long now = SystemClock.uptimeMillis(); 134e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown Message prevMsg = null; 135e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown Message msg = mMessages; 1360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg != null && msg.target == null) { 1370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Stalled by a barrier. Find the next asynchronous message in the queue. 1380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown do { 1390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prevMsg = msg; 1400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg = msg.next; 1410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } while (msg != null && !msg.isAsynchronous()); 1420f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 1430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg != null) { 1440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (now < msg.when) { 145e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // Next message is not ready. Set a timeout to wake up when it is ready. 1460f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); 1470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 148e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // Got a message. 149415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mBlocked = false; 150e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown if (prevMsg != null) { 151e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown prevMsg.next = msg.next; 152e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown } else { 153e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown mMessages = msg.next; 154e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown } 155415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown msg.next = null; 15643a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("MessageQueue", "Returning message: " + msg); 15785c3fe443f7bd06ae0aae6074f4cf2960892cdc0Jeff Brown msg.markInUse(); 158ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown return msg; 159ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 1600f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 1610f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // No more messages. 1620f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown nextPollTimeoutMillis = -1; 16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 164ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown 165e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // If first time idle, then get the number of idlers to run. 1660f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Idle handles only run if the queue is empty or if the first message 1670f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // in the queue (possibly a barrier) is due to be handled in the future. 1680f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (pendingIdleHandlerCount < 0 1690f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown && (mMessages == null || now < mMessages.when)) { 170ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown pendingIdleHandlerCount = mIdleHandlers.size(); 171ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 172e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown if (pendingIdleHandlerCount <= 0) { 173ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // No idle handlers to run. Loop and wait some more. 174415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mBlocked = true; 175ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown continue; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 178ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown if (mPendingIdleHandlers == null) { 179ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 181ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 184ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // Run the idle handlers. 185ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // We only ever reach this code block during the first iteration. 186ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown for (int i = 0; i < pendingIdleHandlerCount; i++) { 187ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown final IdleHandler idler = mPendingIdleHandlers[i]; 188ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mPendingIdleHandlers[i] = null; // release the reference to the handler 189ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown 190ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown boolean keep = false; 191ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown try { 192ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown keep = idler.queueIdle(); 193ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } catch (Throwable t) { 194ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown Log.wtf("MessageQueue", "IdleHandler threw exception", t); 195ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 196ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown 197ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown if (!keep) { 198ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown synchronized (this) { 199ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown mIdleHandlers.remove(idler); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 204ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // Reset the idle handler count to 0 so we do not run them again. 205ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown pendingIdleHandlerCount = 0; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 207ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // While calling an idle handler, a new message could have been delivered 208ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown // so go back and look again for a pending message without waiting. 209ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown nextPollTimeoutMillis = 0; 210ed7393274af2f268fcdede5f1a3d72c9af842b8eJeff Brown } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2130f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final void quit() { 2140f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (!mQuitAllowed) { 2150f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown throw new RuntimeException("Main thread not allowed to quit."); 2160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2180f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 2190f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (mQuiting) { 2200f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 2210f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2220f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mQuiting = true; 2230f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2240f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown nativeWake(mPtr); 2250f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2260f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2270f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final int enqueueSyncBarrier(long when) { 2280f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Enqueue a new sync barrier token. 2290f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // We don't need to wake the queue because the purpose of a barrier is to stall it. 2300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 2310f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final int token = mNextBarrierToken++; 2320f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final Message msg = Message.obtain(); 2330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.arg1 = token; 2340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message prev = null; 2360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message p = mMessages; 2370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (when != 0) { 2380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown while (p != null && p.when <= when) { 2390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev = p; 2400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p = p.next; 2410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2420f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (prev != null) { // invariant: p == prev.next 2440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.next = p; 2450f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev.next = msg; 2460f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 2470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.next = p; 2480f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mMessages = msg; 2490f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2500f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return token; 2510f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2520f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2530f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2540f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final void removeSyncBarrier(int token) { 2550f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Remove a sync barrier token from the queue. 2560f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // If the queue is no longer stalled by a barrier then wake it. 2570f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final boolean needWake; 2580f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 2590f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message prev = null; 2600f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message p = mMessages; 2610f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown while (p != null && (p.target != null || p.arg1 != token)) { 2620f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev = p; 2630f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p = p.next; 2640f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2650f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (p == null) { 2660f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown throw new IllegalStateException("The specified message queue synchronization " 2670f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + " barrier token has not been posted or has already been removed."); 2680f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2690f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (prev != null) { 2700f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prev.next = p.next; 2710f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = false; 2720f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } else { 2730f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mMessages = p.next; 2740f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = mMessages == null || mMessages.target != null; 2750f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2760f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p.recycle(); 2770f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2780f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (needWake) { 2790f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown nativeWake(mPtr); 2800f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2810f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2820f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean enqueueMessage(Message msg, long when) { 284a334e7c72408c4e2805f2427a35d841a60adefc4Wink Saville if (msg.isInUse()) { 2850f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown throw new AndroidRuntimeException(msg + " This message is already in use."); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2870f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg.target == null) { 2880f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown throw new AndroidRuntimeException("Message must have a target."); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2900f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2910f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown boolean needWake; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mQuiting) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RuntimeException e = new RuntimeException( 2950f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.target + " sending message to a Handler on a dead thread"); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("MessageQueue", e.getMessage(), e); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.when = when; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null || when == 0 || when < p.when) { 303e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // New head, wake up the event queue if blocked. 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.next = p; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = msg; 306e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown needWake = mBlocked; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 308e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown // Inserted within the middle of the queue. Usually we don't have to wake 3090f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // up the event queue unless there is a barrier at the head of the queue 3100f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // and the message is the earliest asynchronous message in the queue. 3110f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = mBlocked && p.target == null && msg.isAsynchronous(); 3120f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message prev; 3130f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown for (;;) { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prev = p; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = p.next; 3160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (p == null || when < p.when) { 3170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown break; 3180f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3190f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (needWake && p.isAsynchronous()) { 3200f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown needWake = false; 3210f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3230f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.next = p; // invariant: p == prev.next 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prev.next = msg; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 327415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (needWake) { 328415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown nativeWake(mPtr); 329415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final boolean hasMessages(Handler h, int what, Object object) { 3340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null) { 3350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return false; 3360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 3380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (this) { 3390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Message p = mMessages; 3400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown while (p != null) { 3410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (p.target == h && p.what == what && (object == null || p.obj == object)) { 3420f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return true; 3430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown p = p.next; 345ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 346ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy return false; 347ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 348ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 349ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 350ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy final boolean hasMessages(Handler h, Runnable r, Object object) { 351ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy if (h == null) { 352ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy return false; 353ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 354ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 355ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy synchronized (this) { 356ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy Message p = mMessages; 357ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy while (p != null) { 358ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy if (p.target == h && p.callback == r && (object == null || p.obj == object)) { 359ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy return true; 360ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 361ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy p = p.next; 3620f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3630f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return false; 3640f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3650f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3660f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 3670f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final void removeMessages(Handler h, int what, Object object) { 3680f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null) { 3690f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 3700f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 3710f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages at front. 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null && p.target == h && p.what == what 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || p.obj == object)) { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = n; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.recycle(); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages after front. 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null) { 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != null) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n.target == h && n.what == what 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || n.obj == object)) { 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message nn = n.next; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n.recycle(); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.next = nn; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final void removeMessages(Handler h, Runnable r, Object object) { 4020f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null || r == null) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages at front. 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null && p.target == h && p.callback == r 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || p.obj == object)) { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = n; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.recycle(); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages after front. 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != null) { 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n.target == h && n.callback == r 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || n.obj == object)) { 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message nn = n.next; 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n.recycle(); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.next = nn; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final void removeCallbacksAndMessages(Handler h, Object object) { 4360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (h == null) { 4370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 4380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 4390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message p = mMessages; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages at front. 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null && p.target == h 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (object == null || p.obj == object)) { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessages = n; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.recycle(); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove all messages after front. 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (p != null) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message n = p.next; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != null) { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n.target == h && (object == null || n.obj == object)) { 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message nn = n.next; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n.recycle(); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.next = nn; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p = n; 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 468