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