blob: a2d121d6351cce71715af731e779cbb502311de3 [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
Daniel Sandler325dc232013-06-05 22:57:57 -040017package com.android.launcher3;
Joe Onorato9c1289c2009-08-17 11:03:03 -040018
19import android.os.Handler;
20import android.os.Looper;
21import android.os.Message;
22import android.os.MessageQueue;
Winson Chung81b52252012-08-27 15:34:29 -070023import android.util.Pair;
Michael Jurka34c2e6c2013-12-13 16:07:45 +010024
Winson Chung81b52252012-08-27 15:34:29 -070025import java.util.LinkedList;
26import java.util.ListIterator;
Joe Onorato9c1289c2009-08-17 11:03:03 -040027
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 */
35public class DeferredHandler {
Winson Chung81b52252012-08-27 15:34:29 -070036 private LinkedList<Pair<Runnable, Integer>> mQueue = new LinkedList<Pair<Runnable, Integer>>();
Joe Onorato9c1289c2009-08-17 11:03:03 -040037 private MessageQueue mMessageQueue = Looper.myQueue();
38 private Impl mHandler = new Impl();
39
40 private class Impl extends Handler implements MessageQueue.IdleHandler {
41 public void handleMessage(Message msg) {
Winson Chung81b52252012-08-27 15:34:29 -070042 Pair<Runnable, Integer> p;
Joe Onorato9c1289c2009-08-17 11:03:03 -040043 Runnable r;
44 synchronized (mQueue) {
Joe Onorato33ed7b22009-09-23 18:20:54 -070045 if (mQueue.size() == 0) {
46 return;
47 }
Winson Chung81b52252012-08-27 15:34:29 -070048 p = mQueue.removeFirst();
49 r = p.first;
Joe Onorato9c1289c2009-08-17 11:03:03 -040050 }
51 r.run();
52 synchronized (mQueue) {
53 scheduleNextLocked();
54 }
55 }
56
57 public boolean queueIdle() {
58 handleMessage(null);
59 return false;
60 }
61 }
62
63 private class IdleRunnable implements Runnable {
64 Runnable mRunnable;
65
66 IdleRunnable(Runnable r) {
67 mRunnable = r;
68 }
69
70 public void run() {
71 mRunnable.run();
72 }
73 }
74
75 public DeferredHandler() {
76 }
77
78 /** Schedule runnable to run after everything that's on the queue right now. */
79 public void post(Runnable runnable) {
Winson Chung81b52252012-08-27 15:34:29 -070080 post(runnable, 0);
81 }
82 public void post(Runnable runnable, int type) {
Joe Onorato9c1289c2009-08-17 11:03:03 -040083 synchronized (mQueue) {
Winson Chung81b52252012-08-27 15:34:29 -070084 mQueue.add(new Pair<Runnable, Integer>(runnable, type));
Joe Onorato9c1289c2009-08-17 11:03:03 -040085 if (mQueue.size() == 1) {
86 scheduleNextLocked();
87 }
88 }
89 }
90
91 /** Schedule runnable to run when the queue goes idle. */
92 public void postIdle(final Runnable runnable) {
Winson Chung81b52252012-08-27 15:34:29 -070093 postIdle(runnable, 0);
94 }
95 public void postIdle(final Runnable runnable, int type) {
96 post(new IdleRunnable(runnable), type);
Joe Onorato9c1289c2009-08-17 11:03:03 -040097 }
98
Daniel Sandlerdca66122010-04-13 16:23:58 -040099 public void cancelRunnable(Runnable runnable) {
100 synchronized (mQueue) {
101 while (mQueue.remove(runnable)) { }
102 }
103 }
Winson Chung81b52252012-08-27 15:34:29 -0700104 public void cancelAllRunnablesOfType(int type) {
105 synchronized (mQueue) {
106 ListIterator<Pair<Runnable, Integer>> iter = mQueue.listIterator();
107 Pair<Runnable, Integer> p;
108 while (iter.hasNext()) {
109 p = iter.next();
110 if (p.second == type) {
111 iter.remove();
112 }
113 }
114 }
115 }
Daniel Sandlerdca66122010-04-13 16:23:58 -0400116
Joe Onorato9c1289c2009-08-17 11:03:03 -0400117 public void cancel() {
118 synchronized (mQueue) {
119 mQueue.clear();
120 }
121 }
122
Adam Cohena13a2f22012-07-23 14:29:15 -0700123 /** Runs all queued Runnables from the calling thread. */
124 public void flush() {
Winson Chung81b52252012-08-27 15:34:29 -0700125 LinkedList<Pair<Runnable, Integer>> queue = new LinkedList<Pair<Runnable, Integer>>();
Adam Cohena13a2f22012-07-23 14:29:15 -0700126 synchronized (mQueue) {
127 queue.addAll(mQueue);
128 mQueue.clear();
129 }
Winson Chung81b52252012-08-27 15:34:29 -0700130 for (Pair<Runnable, Integer> p : queue) {
131 p.first.run();
Adam Cohena13a2f22012-07-23 14:29:15 -0700132 }
133 }
134
Joe Onorato9c1289c2009-08-17 11:03:03 -0400135 void scheduleNextLocked() {
136 if (mQueue.size() > 0) {
Winson Chung81b52252012-08-27 15:34:29 -0700137 Pair<Runnable, Integer> p = mQueue.getFirst();
138 Runnable peek = p.first;
Joe Onorato9c1289c2009-08-17 11:03:03 -0400139 if (peek instanceof IdleRunnable) {
140 mMessageQueue.addIdleHandler(mHandler);
141 } else {
142 mHandler.sendEmptyMessage(1);
143 }
144 }
145 }
146}
147