Home | History | Annotate | Download | only in launcher2
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.launcher2;
     18 
     19 import java.util.LinkedList;
     20 
     21 import android.os.Handler;
     22 import android.os.Looper;
     23 import android.os.Message;
     24 import android.os.MessageQueue;
     25 
     26 /**
     27  * Queue of things to run on a looper thread.  Items posted with {@link #post} will not
     28  * be actually enqued on the handler until after the last one has run, to keep from
     29  * starving the thread.
     30  *
     31  * This class is fifo.
     32  */
     33 public class DeferredHandler {
     34     private LinkedList<Runnable> mQueue = new LinkedList<Runnable>();
     35     private MessageQueue mMessageQueue = Looper.myQueue();
     36     private Impl mHandler = new Impl();
     37 
     38     private class Impl extends Handler implements MessageQueue.IdleHandler {
     39         public void handleMessage(Message msg) {
     40             Runnable r;
     41             synchronized (mQueue) {
     42                 if (mQueue.size() == 0) {
     43                     return;
     44                 }
     45                 r = mQueue.removeFirst();
     46             }
     47             r.run();
     48             synchronized (mQueue) {
     49                 scheduleNextLocked();
     50             }
     51         }
     52 
     53         public boolean queueIdle() {
     54             handleMessage(null);
     55             return false;
     56         }
     57     }
     58 
     59     private class IdleRunnable implements Runnable {
     60         Runnable mRunnable;
     61 
     62         IdleRunnable(Runnable r) {
     63             mRunnable = r;
     64         }
     65 
     66         public void run() {
     67             mRunnable.run();
     68         }
     69     }
     70 
     71     public DeferredHandler() {
     72     }
     73 
     74     /** Schedule runnable to run after everything that's on the queue right now. */
     75     public void post(Runnable runnable) {
     76         synchronized (mQueue) {
     77             mQueue.add(runnable);
     78             if (mQueue.size() == 1) {
     79                 scheduleNextLocked();
     80             }
     81         }
     82     }
     83 
     84     /** Schedule runnable to run when the queue goes idle. */
     85     public void postIdle(final Runnable runnable) {
     86         post(new IdleRunnable(runnable));
     87     }
     88 
     89     public void cancelRunnable(Runnable runnable) {
     90         synchronized (mQueue) {
     91             while (mQueue.remove(runnable)) { }
     92         }
     93     }
     94 
     95     public void cancel() {
     96         synchronized (mQueue) {
     97             mQueue.clear();
     98         }
     99     }
    100 
    101     void scheduleNextLocked() {
    102         if (mQueue.size() > 0) {
    103             Runnable peek = mQueue.getFirst();
    104             if (peek instanceof IdleRunnable) {
    105                 mMessageQueue.addIdleHandler(mHandler);
    106             } else {
    107                 mHandler.sendEmptyMessage(1);
    108             }
    109         }
    110     }
    111 }
    112 
    113