blob: 930da56aa0fb5d53e9f237ca0976b9057b5c01d2 [file] [log] [blame]
Joe Onorato9c1289c2009-08-17 11:03:03 -04001/*
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
17package com.android.launcher2;
18
Winson Chungaafa03c2010-06-11 17:34:16 -070019import java.util.LinkedList;
20
Joe Onorato9c1289c2009-08-17 11:03:03 -040021import android.os.Handler;
22import android.os.Looper;
23import android.os.Message;
24import android.os.MessageQueue;
Joe Onorato9c1289c2009-08-17 11:03:03 -040025
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 */
33public class DeferredHandler {
Michael Jurka4a7d4af2011-01-17 15:31:53 -080034 private LinkedList<Runnable> mQueue = new LinkedList<Runnable>();
Joe Onorato9c1289c2009-08-17 11:03:03 -040035 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) {
Joe Onorato33ed7b22009-09-23 18:20:54 -070042 if (mQueue.size() == 0) {
43 return;
44 }
Joe Onorato9c1289c2009-08-17 11:03:03 -040045 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
Daniel Sandlerdca66122010-04-13 16:23:58 -040089 public void cancelRunnable(Runnable runnable) {
90 synchronized (mQueue) {
91 while (mQueue.remove(runnable)) { }
92 }
93 }
94
Joe Onorato9c1289c2009-08-17 11:03:03 -040095 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