19c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato/*
29c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Copyright (C) 2008 The Android Open Source Project
39c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato *
49c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
59c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * you may not use this file except in compliance with the License.
69c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * You may obtain a copy of the License at
79c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato *
89c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
99c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato *
109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Unless required by applicable law or agreed to in writing, software
119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * See the License for the specific language governing permissions and
149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * limitations under the License.
159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */
169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratopackage com.android.launcher2;
189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
19aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport java.util.LinkedList;
20aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.Handler;
229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.Looper;
239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.Message;
249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.MessageQueue;
259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato/**
279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Queue of things to run on a looper thread.  Items posted with {@link #post} will not
289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * be actually enqued on the handler until after the last one has run, to keep from
299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * starving the thread.
309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato *
319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * This class is fifo.
329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */
339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratopublic class DeferredHandler {
344a7d4afe87a9146b3cefef8e00581090301b698dMichael Jurka    private LinkedList<Runnable> mQueue = new LinkedList<Runnable>();
359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private MessageQueue mMessageQueue = Looper.myQueue();
369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private Impl mHandler = new Impl();
379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private class Impl extends Handler implements MessageQueue.IdleHandler {
399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void handleMessage(Message msg) {
409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            Runnable r;
419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mQueue) {
4233ed7b2f5a2456dc44dfe6e8f35a415c1495a87cJoe Onorato                if (mQueue.size() == 0) {
4333ed7b2f5a2456dc44dfe6e8f35a415c1495a87cJoe Onorato                    return;
4433ed7b2f5a2456dc44dfe6e8f35a415c1495a87cJoe Onorato                }
459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                r = mQueue.removeFirst();
469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            r.run();
489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mQueue) {
499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                scheduleNextLocked();
509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public boolean queueIdle() {
549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            handleMessage(null);
559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            return false;
569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private class IdleRunnable implements Runnable {
609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        Runnable mRunnable;
619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        IdleRunnable(Runnable r) {
639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            mRunnable = r;
649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void run() {
679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            mRunnable.run();
689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public DeferredHandler() {
729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /** Schedule runnable to run after everything that's on the queue right now. */
759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void post(Runnable runnable) {
769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        synchronized (mQueue) {
779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            mQueue.add(runnable);
789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (mQueue.size() == 1) {
799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                scheduleNextLocked();
809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /** Schedule runnable to run when the queue goes idle. */
859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void postIdle(final Runnable runnable) {
869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        post(new IdleRunnable(runnable));
879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
89dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler    public void cancelRunnable(Runnable runnable) {
90dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler        synchronized (mQueue) {
91dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler            while (mQueue.remove(runnable)) { }
92dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler        }
93dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler    }
94dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler
959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void cancel() {
969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        synchronized (mQueue) {
979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            mQueue.clear();
989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
1009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
1019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    void scheduleNextLocked() {
1029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (mQueue.size() > 0) {
1039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            Runnable peek = mQueue.getFirst();
1049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (peek instanceof IdleRunnable) {
1059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mMessageQueue.addIdleHandler(mHandler);
1069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            } else {
1079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.sendEmptyMessage(1);
1089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
1099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
1109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
1119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato}
1129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
113