• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
handleMessage(Message msg)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 
queueIdle()53         public boolean queueIdle() {
54             handleMessage(null);
55             return false;
56         }
57     }
58 
59     private class IdleRunnable implements Runnable {
60         Runnable mRunnable;
61 
IdleRunnable(Runnable r)62         IdleRunnable(Runnable r) {
63             mRunnable = r;
64         }
65 
run()66         public void run() {
67             mRunnable.run();
68         }
69     }
70 
DeferredHandler()71     public DeferredHandler() {
72     }
73 
74     /** Schedule runnable to run after everything that's on the queue right now. */
post(Runnable runnable)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. */
postIdle(final Runnable runnable)85     public void postIdle(final Runnable runnable) {
86         post(new IdleRunnable(runnable));
87     }
88 
cancelRunnable(Runnable runnable)89     public void cancelRunnable(Runnable runnable) {
90         synchronized (mQueue) {
91             while (mQueue.remove(runnable)) { }
92         }
93     }
94 
cancel()95     public void cancel() {
96         synchronized (mQueue) {
97             mQueue.clear();
98         }
99     }
100 
scheduleNextLocked()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