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