DeferredHandler.java revision 091440a9cb9d4f42406631004aa484cbb79214ca
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
17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3;
189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.Handler;
209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.Looper;
219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.Message;
229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.MessageQueue;
2381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chungimport android.util.Pair;
2434c2e6cf7af328aba25c98158161dbad15ae986dMichael Jurka
25091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
26091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen
2781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chungimport java.util.LinkedList;
2881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chungimport java.util.ListIterator;
299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato/**
319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Queue of things to run on a looper thread.  Items posted with {@link #post} will not
329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * be actually enqued on the handler until after the last one has run, to keep from
339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * starving the thread.
349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato *
359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * This class is fifo.
369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */
379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratopublic class DeferredHandler {
38091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk LinkedList<Pair<Runnable, Integer>> mQueue = new LinkedList<Pair<Runnable, Integer>>();
399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private MessageQueue mMessageQueue = Looper.myQueue();
409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private Impl mHandler = new Impl();
419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
42091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk class Impl extends Handler implements MessageQueue.IdleHandler {
439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void handleMessage(Message msg) {
4481b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung            Pair<Runnable, Integer> p;
459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            Runnable r;
469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mQueue) {
4733ed7b2f5a2456dc44dfe6e8f35a415c1495a87cJoe Onorato                if (mQueue.size() == 0) {
4833ed7b2f5a2456dc44dfe6e8f35a415c1495a87cJoe Onorato                    return;
4933ed7b2f5a2456dc44dfe6e8f35a415c1495a87cJoe Onorato                }
5081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung                p = mQueue.removeFirst();
5181b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung                r = p.first;
529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            r.run();
549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            synchronized (mQueue) {
559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                scheduleNextLocked();
569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public boolean queueIdle() {
609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            handleMessage(null);
619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            return false;
629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    private class IdleRunnable implements Runnable {
669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        Runnable mRunnable;
679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        IdleRunnable(Runnable r) {
699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            mRunnable = r;
709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        public void run() {
739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            mRunnable.run();
749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public DeferredHandler() {
789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /** Schedule runnable to run after everything that's on the queue right now. */
819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void post(Runnable runnable) {
8281b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung        post(runnable, 0);
8381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung    }
8481b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung    public void post(Runnable runnable, int type) {
859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        synchronized (mQueue) {
8681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung            mQueue.add(new Pair<Runnable, Integer>(runnable, type));
879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (mQueue.size() == 1) {
889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                scheduleNextLocked();
899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    /** Schedule runnable to run when the queue goes idle. */
949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void postIdle(final Runnable runnable) {
9581b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung        postIdle(runnable, 0);
9681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung    }
9781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung    public void postIdle(final Runnable runnable, int type) {
9881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung        post(new IdleRunnable(runnable), type);
999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
1009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
101dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler    public void cancelRunnable(Runnable runnable) {
102dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler        synchronized (mQueue) {
103dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler            while (mQueue.remove(runnable)) { }
104dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler        }
105dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler    }
10681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung    public void cancelAllRunnablesOfType(int type) {
10781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung        synchronized (mQueue) {
10881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung            ListIterator<Pair<Runnable, Integer>> iter = mQueue.listIterator();
10981b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung            Pair<Runnable, Integer> p;
11081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung            while (iter.hasNext()) {
11181b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung                p = iter.next();
11281b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung                if (p.second == type) {
11381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung                    iter.remove();
11481b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung                }
11581b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung            }
11681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung        }
11781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung    }
118dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler
1199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    public void cancel() {
1209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        synchronized (mQueue) {
1219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            mQueue.clear();
1229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
1239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
1249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
125a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen    /** Runs all queued Runnables from the calling thread. */
126a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen    public void flush() {
12781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung        LinkedList<Pair<Runnable, Integer>> queue = new LinkedList<Pair<Runnable, Integer>>();
128a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen        synchronized (mQueue) {
129a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen            queue.addAll(mQueue);
130a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen            mQueue.clear();
131a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen        }
13281b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung        for (Pair<Runnable, Integer> p : queue) {
13381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung            p.first.run();
134a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen        }
135a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen    }
136a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen
1379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    void scheduleNextLocked() {
1389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (mQueue.size() > 0) {
13981b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung            Pair<Runnable, Integer> p = mQueue.getFirst();
14081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung            Runnable peek = p.first;
1419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            if (peek instanceof IdleRunnable) {
1429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mMessageQueue.addIdleHandler(mHandler);
1439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            } else {
1449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                mHandler.sendEmptyMessage(1);
1459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato            }
1469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
1479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato    }
1489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato}
1499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato
150