OSDN Git Service

resolved conflicts for merge of 13ef17a3 to mnc-dr-dev
[android-x86/packages-apps-Launcher3.git] / src / com / android / launcher3 / DeferredHandler.java
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.launcher3;
18
19 import android.os.Handler;
20 import android.os.Looper;
21 import android.os.Message;
22 import android.os.MessageQueue;
23
24 import com.android.launcher3.util.Thunk;
25
26 import java.util.LinkedList;
27
28 /**
29  * Queue of things to run on a looper thread.  Items posted with {@link #post} will not
30  * be actually enqued on the handler until after the last one has run, to keep from
31  * starving the thread.
32  *
33  * This class is fifo.
34  */
35 public class DeferredHandler {
36     @Thunk LinkedList<Runnable> mQueue = new LinkedList<>();
37     private MessageQueue mMessageQueue = Looper.myQueue();
38     private Impl mHandler = new Impl();
39
40     @Thunk class Impl extends Handler implements MessageQueue.IdleHandler {
41         public void handleMessage(Message msg) {
42             Runnable r;
43             synchronized (mQueue) {
44                 if (mQueue.size() == 0) {
45                     return;
46                 }
47                 r = mQueue.removeFirst();
48             }
49             r.run();
50             synchronized (mQueue) {
51                 scheduleNextLocked();
52             }
53         }
54
55         public boolean queueIdle() {
56             handleMessage(null);
57             return false;
58         }
59     }
60
61     private class IdleRunnable implements Runnable {
62         Runnable mRunnable;
63
64         IdleRunnable(Runnable r) {
65             mRunnable = r;
66         }
67
68         public void run() {
69             mRunnable.run();
70         }
71     }
72
73     public DeferredHandler() {
74     }
75
76     /** Schedule runnable to run after everything that's on the queue right now. */
77     public void post(Runnable runnable) {
78         synchronized (mQueue) {
79             mQueue.add(runnable);
80             if (mQueue.size() == 1) {
81                 scheduleNextLocked();
82             }
83         }
84     }
85
86     /** Schedule runnable to run when the queue goes idle. */
87     public void postIdle(final Runnable runnable) {
88         post(new IdleRunnable(runnable));
89     }
90
91     public void cancelAll() {
92         synchronized (mQueue) {
93             mQueue.clear();
94         }
95     }
96
97     /** Runs all queued Runnables from the calling thread. */
98     public void flush() {
99         LinkedList<Runnable> queue = new LinkedList<>();
100         synchronized (mQueue) {
101             queue.addAll(mQueue);
102             mQueue.clear();
103         }
104         for (Runnable r : queue) {
105             r.run();
106         }
107     }
108
109     void scheduleNextLocked() {
110         if (mQueue.size() > 0) {
111             Runnable peek = mQueue.getFirst();
112             if (peek instanceof IdleRunnable) {
113                 mMessageQueue.addIdleHandler(mHandler);
114             } else {
115                 mHandler.sendEmptyMessage(1);
116             }
117         }
118     }
119 }
120