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