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
191b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrickimport android.util.Log;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer;
211b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrickimport android.util.PrefixPrinter;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * Class used to run a message loop for a thread.  Threads by default do
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * not have a message loop associated with them; to create one, call
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * {@link #prepare} in the thread that is to run the loop, and then
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * {@link #loop} to have it process messages until the loop is stopped.
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * <p>Most interaction with a message loop is through the
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * {@link Handler} class.
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * <p>This is a typical example of the implementation of a Looper thread,
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * using the separation of {@link #prepare} and {@link #loop} to create an
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * initial Handler to communicate with the Looper.
351b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick  *
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  * <pre>
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *  class LooperThread extends Thread {
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *      public Handler mHandler;
391b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick  *
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *      public void run() {
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *          Looper.prepare();
421b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick  *
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *          mHandler = new Handler() {
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *              public void handleMessage(Message msg) {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *                  // process incoming messages here
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *              }
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *          };
481b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick  *
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *          Looper.loop();
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *      }
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  *  }</pre>
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  */
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Looper {
541b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick    private static final String TAG = "Looper";
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // sThreadLocal.get() will return null unless you've called prepare().
577f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
580f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    private static Looper sMainLooper;  // guarded by Looper.class
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final MessageQueue mQueue;
611b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick    final Thread mThread;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    volatile boolean mRun;
631b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick
640f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    private Printer mLogging;
651b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /** Initialize the current thread as a looper.
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      * This gives you a chance to create handlers that then reference
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      * this looper, before actually starting the loop. Be sure to call
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      * {@link #loop()} after calling this method, and end it by calling
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      * {@link #quit()}.
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      */
72f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy    public static void prepare() {
730f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        prepare(true);
740f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    }
750f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown
760f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    private static void prepare(boolean quitAllowed) {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sThreadLocal.get() != null) {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Only one Looper may be created per thread");
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
800f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        sThreadLocal.set(new Looper(quitAllowed));
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
821b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick
831b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick    /**
841b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick     * Initialize the current thread as a looper, marking it as an
851b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick     * application's main looper. The main looper for your application
861b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick     * is created by the Android environment, so you should never need
871b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick     * to call this function yourself.  See also: {@link #prepare()}
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
89f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy    public static void prepareMainLooper() {
900f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        prepare(false);
910f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        synchronized (Looper.class) {
920f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            if (sMainLooper != null) {
930f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                throw new IllegalStateException("The main Looper has already been prepared.");
940f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            }
950f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            sMainLooper = myLooper();
960f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
981b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Returns the application's main looper, which lives in the main thread of the application.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1010f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    public static Looper getMainLooper() {
1020f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        synchronized (Looper.class) {
1030f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            return sMainLooper;
1040f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1081b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick     * Run the message queue in this thread. Be sure to call
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #quit()} to end the loop.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
111f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy    public static void loop() {
1120f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        final Looper me = myLooper();
1131b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick        if (me == null) {
1141b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
1151b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick        }
1160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        final MessageQueue queue = me.mQueue;
1170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown
118e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn        // Make sure the identity of this thread is that of the local process,
119e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn        // and keep track of what that identity token actually is.
120e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn        Binder.clearCallingIdentity();
121e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn        final long ident = Binder.clearCallingIdentity();
1220f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown
1230f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        for (;;) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Message msg = queue.next(); // might block
1250f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            if (msg == null) {
1260f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                // No message indicates that the message queue is quitting.
1270f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                return;
1280f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            }
129f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy
1300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            // This must be in a local variable, in case a UI event sets the logger
1310f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            Printer logging = me.mLogging;
1320f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            if (logging != null) {
1330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                logging.println(">>>>> Dispatching to " + msg.target + " " +
1340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                        msg.callback + ": " + msg.what);
1350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            }
136f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy
1370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            msg.target.dispatchMessage(msg);
138f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy
1390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            if (logging != null) {
1400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
1410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            }
142f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy
1430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            // Make sure that during the course of dispatching the
1440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            // identity of the thread wasn't corrupted.
1450f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            final long newIdent = Binder.clearCallingIdentity();
1460f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            if (ident != newIdent) {
1470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                Log.wtf(TAG, "Thread identity changed from 0x"
1480f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                        + Long.toHexString(ident) + " to 0x"
1490f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                        + Long.toHexString(newIdent) + " while dispatching to "
1500f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                        + msg.target.getClass().getName() + " "
1510f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown                        + msg.callback + " what=" + msg.what);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1530f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown
1540f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown            msg.recycle();
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the Looper object associated with the current thread.  Returns
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * null if the calling thread is not associated with a Looper.
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
162f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy    public static Looper myLooper() {
1631b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick        return sThreadLocal.get();
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control logging of messages as they are processed by this Looper.  If
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * enabled, a log message will be written to <var>printer</var>
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * at the beginning and ending of each message dispatch, identifying the
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * target Handler and message contents.
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param printer A Printer object that will receive log messages, or
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * null to disable message logging.
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setMessageLogging(Printer printer) {
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLogging = printer;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the {@link MessageQueue} object associated with the current
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * thread.  This must be called from a thread running a Looper, or a
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * NullPointerException will be thrown.
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
184f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy    public static MessageQueue myQueue() {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return myLooper().mQueue;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1880f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    private Looper(boolean quitAllowed) {
1890f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        mQueue = new MessageQueue(quitAllowed);
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRun = true;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mThread = Thread.currentThread();
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1940f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    /**
1950f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * Quits the looper.
1960f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     *
1970f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * Causes the {@link #loop} method to terminate as soon as possible.
1980f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     */
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void quit() {
2000f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        mQueue.quit();
2010f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    }
2020f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown
2030f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    /**
2040f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * Posts a synchronization barrier to the Looper's message queue.
2050f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     *
2060f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * Message processing occurs as usual until the message queue encounters the
2070f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * synchronization barrier that has been posted.  When the barrier is encountered,
2080f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * later synchronous messages in the queue are stalled (prevented from being executed)
2090f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * until the barrier is released by calling {@link #removeSyncBarrier} and specifying
2100f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * the token that identifies the synchronization barrier.
2110f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     *
2120f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * This method is used to immediately postpone execution of all subsequently posted
2130f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * synchronous messages until a condition is met that releases the barrier.
2140f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier
2150f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * and continue to be processed as usual.
2160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     *
2170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * This call must be always matched by a call to {@link #removeSyncBarrier} with
2180f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * the same token to ensure that the message queue resumes normal operation.
2190f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * Otherwise the application will probably hang!
2200f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     *
2210f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * @return A token that uniquely identifies the barrier.  This token must be
2220f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * passed to {@link #removeSyncBarrier} to release the barrier.
2230f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     *
2240f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * @hide
2250f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     */
2260f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    public final int postSyncBarrier() {
2270f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        return mQueue.enqueueSyncBarrier(SystemClock.uptimeMillis());
2280f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    }
2290f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown
2300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown
2310f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    /**
2320f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * Removes a synchronization barrier.
2330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     *
2340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * @param token The synchronization barrier token that was returned by
2350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * {@link #postSyncBarrier}.
2360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     *
2370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * @throws IllegalStateException if the barrier was not found.
2380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     *
2390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     * @hide
2400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown     */
2410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown    public final void removeSyncBarrier(int token) {
2420f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown        mQueue.removeSyncBarrier(token);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the Thread associated with this Looper.
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Thread getThread() {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mThread;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2511b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick
252a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown    /** @hide */
253a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown    public MessageQueue getQueue() {
254a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown        return mQueue;
255a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown    }
2561b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dump(Printer pw, String prefix) {
2581b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick        pw = PrefixPrinter.create(pw, prefix);
2591b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick        pw.println(this.toString());
2601b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick        pw.println("mRun=" + mRun);
2611b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick        pw.println("mThread=" + mThread);
2621b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick        pw.println("mQueue=" + ((mQueue != null) ? mQueue : "(null"));
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mQueue != null) {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mQueue) {
2651ebccf531d1049853b3b0630035434619682c016Dianne Hackborn                long now = SystemClock.uptimeMillis();
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Message msg = mQueue.mMessages;
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int n = 0;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                while (msg != null) {
2691b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick                    pw.println("  Message " + n + ": " + msg.toString(now));
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    n++;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    msg = msg.next;
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2731b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick                pw.println("(Total messages: " + n + ")");
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String toString() {
279f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy        return "Looper{" + Integer.toHexString(System.identityHashCode(this)) + "}";
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
282