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; 2334c2e6cf7af328aba25c98158161dbad15ae986dMichael Jurka 24091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 25091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen 2681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chungimport java.util.LinkedList; 279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato/** 299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Queue of things to run on a looper thread. Items posted with {@link #post} will not 309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * be actually enqued on the handler until after the last one has run, to keep from 319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * starving the thread. 329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * 339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * This class is fifo. 349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratopublic class DeferredHandler { 36d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal @Thunk LinkedList<Runnable> mQueue = new LinkedList<>(); 379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private MessageQueue mMessageQueue = Looper.myQueue(); 389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private Impl mHandler = new Impl(); 399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 40091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk class Impl extends Handler implements MessageQueue.IdleHandler { 419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void handleMessage(Message msg) { 429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Runnable r; 439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mQueue) { 4433ed7b2f5a2456dc44dfe6e8f35a415c1495a87cJoe Onorato if (mQueue.size() == 0) { 4533ed7b2f5a2456dc44dfe6e8f35a415c1495a87cJoe Onorato return; 4633ed7b2f5a2456dc44dfe6e8f35a415c1495a87cJoe Onorato } 47d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal r = mQueue.removeFirst(); 489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato r.run(); 509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mQueue) { 519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato scheduleNextLocked(); 529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public boolean queueIdle() { 569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato handleMessage(null); 579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return false; 589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private class IdleRunnable implements Runnable { 629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Runnable mRunnable; 639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato IdleRunnable(Runnable r) { 659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mRunnable = r; 669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mRunnable.run(); 709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public DeferredHandler() { 749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** Schedule runnable to run after everything that's on the queue right now. */ 779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void post(Runnable runnable) { 789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mQueue) { 79d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal mQueue.add(runnable); 809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mQueue.size() == 1) { 819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato scheduleNextLocked(); 829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** Schedule runnable to run when the queue goes idle. */ 879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void postIdle(final Runnable runnable) { 88d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal post(new IdleRunnable(runnable)); 8981b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung } 90dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 91d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal public void cancelAll() { 929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mQueue) { 939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mQueue.clear(); 949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 97a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen /** Runs all queued Runnables from the calling thread. */ 98a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen public void flush() { 99d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal LinkedList<Runnable> queue = new LinkedList<>(); 100a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen synchronized (mQueue) { 101a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen queue.addAll(mQueue); 102a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen mQueue.clear(); 103a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen } 104d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal for (Runnable r : queue) { 105d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal r.run(); 106a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen } 107a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen } 108a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen 1099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato void scheduleNextLocked() { 1109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (mQueue.size() > 0) { 111d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal Runnable peek = mQueue.getFirst(); 1129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (peek instanceof IdleRunnable) { 1139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mMessageQueue.addIdleHandler(mHandler); 1149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else { 1159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mHandler.sendEmptyMessage(1); 1169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato} 1209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 121