blob: 7ca5d498ae5c8409ac30fd6036e242752b5ccd60 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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 android.os;
18
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import android.util.AndroidRuntimeException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.util.Log;
Jeff Brown5182c782013-10-15 20:31:52 -070021import android.util.Printer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
Jeff Brown46b9ac02010-04-22 18:58:52 -070023import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
25/**
26 * Low-level class holding the list of messages to be dispatched by a
27 * {@link Looper}. Messages are not added directly to a MessageQueue,
28 * but rather through {@link Handler} objects associated with the Looper.
29 *
30 * <p>You can retrieve the MessageQueue for the current thread with
31 * {@link Looper#myQueue() Looper.myQueue()}.
32 */
Jeff Brown67fc67c2013-04-01 13:00:33 -070033public final class MessageQueue {
Jeff Brown0f85ce32012-02-16 14:41:10 -080034 // True if the message queue can be quit.
35 private final boolean mQuitAllowed;
36
37 @SuppressWarnings("unused")
Ashok Bhat63a37152014-01-10 14:15:21 +000038 private long mPtr; // used by native code
Jeff Brown0f85ce32012-02-16 14:41:10 -080039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 Message mMessages;
Jeff Brown46b9ac02010-04-22 18:58:52 -070041 private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
Jeff Browned739322010-09-21 15:14:14 -070042 private IdleHandler[] mPendingIdleHandlers;
Jeff Brown013cf842013-09-06 16:24:36 -070043 private boolean mQuitting;
Christopher Tatefa9e7c02010-05-06 12:07:10 -070044
Jeff Brown415d8c32010-10-05 15:35:37 -070045 // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
46 private boolean mBlocked;
47
Jeff Brown0f85ce32012-02-16 14:41:10 -080048 // The next barrier token.
49 // Barriers are indicated by messages with a null target whose arg1 field carries the token.
50 private int mNextBarrierToken;
Jeff Browne799cb72012-02-14 11:53:33 -080051
Ashok Bhat63a37152014-01-10 14:15:21 +000052 private native static long nativeInit();
53 private native static void nativeDestroy(long ptr);
54 private native static void nativePollOnce(long ptr, int timeoutMillis);
55 private native static void nativeWake(long ptr);
56 private native static boolean nativeIsIdling(long ptr);
Jeff Brown46b9ac02010-04-22 18:58:52 -070057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 /**
59 * Callback interface for discovering when a thread is going to block
60 * waiting for more messages.
61 */
62 public static interface IdleHandler {
63 /**
64 * Called when the message queue has run out of messages and will now
65 * wait for more. Return true to keep your idle handler active, false
66 * to have it removed. This may be called if there are still messages
67 * pending in the queue, but they are all scheduled to be dispatched
68 * after the current time.
69 */
70 boolean queueIdle();
71 }
72
73 /**
74 * Add a new {@link IdleHandler} to this message queue. This may be
75 * removed automatically for you by returning false from
76 * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
77 * invoked, or explicitly removing it with {@link #removeIdleHandler}.
78 *
79 * <p>This method is safe to call from any thread.
80 *
81 * @param handler The IdleHandler to be added.
82 */
Jeff Brown67fc67c2013-04-01 13:00:33 -070083 public void addIdleHandler(IdleHandler handler) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 if (handler == null) {
85 throw new NullPointerException("Can't add a null IdleHandler");
86 }
87 synchronized (this) {
88 mIdleHandlers.add(handler);
89 }
90 }
91
92 /**
93 * Remove an {@link IdleHandler} from the queue that was previously added
94 * with {@link #addIdleHandler}. If the given object is not currently
95 * in the idle list, nothing is done.
96 *
97 * @param handler The IdleHandler to be removed.
98 */
Jeff Brown67fc67c2013-04-01 13:00:33 -070099 public void removeIdleHandler(IdleHandler handler) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 synchronized (this) {
101 mIdleHandlers.remove(handler);
102 }
103 }
Jeff Browne799cb72012-02-14 11:53:33 -0800104
Jeff Brown0f85ce32012-02-16 14:41:10 -0800105 MessageQueue(boolean quitAllowed) {
106 mQuitAllowed = quitAllowed;
Jeff Brown864693462013-01-28 14:25:53 -0800107 mPtr = nativeInit();
Christopher Tatefa9e7c02010-05-06 12:07:10 -0700108 }
Jeff Brown0f85ce32012-02-16 14:41:10 -0800109
Jeff Brown46b9ac02010-04-22 18:58:52 -0700110 @Override
111 protected void finalize() throws Throwable {
112 try {
Jeff Brown864693462013-01-28 14:25:53 -0800113 dispose();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700114 } finally {
115 super.finalize();
116 }
117 }
Christopher Tatefa9e7c02010-05-06 12:07:10 -0700118
Jeff Brown013cf842013-09-06 16:24:36 -0700119 // Disposes of the underlying message queue.
120 // Must only be called on the looper thread or the finalizer.
Jeff Brown864693462013-01-28 14:25:53 -0800121 private void dispose() {
122 if (mPtr != 0) {
123 nativeDestroy(mPtr);
124 mPtr = 0;
125 }
126 }
127
Jeff Brown67fc67c2013-04-01 13:00:33 -0700128 Message next() {
Jeff Brown60583902013-09-09 16:14:20 -0700129 // Return here if the message loop has already quit and been disposed.
130 // This can happen if the application tries to restart a looper after quit
131 // which is not supported.
Narayan Kamathab864342014-01-16 11:22:52 +0000132 final long ptr = mPtr;
Jeff Brown60583902013-09-09 16:14:20 -0700133 if (ptr == 0) {
134 return null;
135 }
136
Jeff Browned739322010-09-21 15:14:14 -0700137 int pendingIdleHandlerCount = -1; // -1 only during first iteration
138 int nextPollTimeoutMillis = 0;
Jeff Browned739322010-09-21 15:14:14 -0700139 for (;;) {
140 if (nextPollTimeoutMillis != 0) {
141 Binder.flushPendingCommands();
142 }
Jeff Brown013cf842013-09-06 16:24:36 -0700143
Jeff Brown60583902013-09-09 16:14:20 -0700144 nativePollOnce(ptr, nextPollTimeoutMillis);
Christopher Tatefa9e7c02010-05-06 12:07:10 -0700145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 synchronized (this) {
Jeff Browned739322010-09-21 15:14:14 -0700147 // Try to retrieve the next message. Return if found.
148 final long now = SystemClock.uptimeMillis();
Jeff Browne799cb72012-02-14 11:53:33 -0800149 Message prevMsg = null;
150 Message msg = mMessages;
Jeff Brown0f85ce32012-02-16 14:41:10 -0800151 if (msg != null && msg.target == null) {
152 // Stalled by a barrier. Find the next asynchronous message in the queue.
153 do {
154 prevMsg = msg;
155 msg = msg.next;
156 } while (msg != null && !msg.isAsynchronous());
157 }
158 if (msg != null) {
159 if (now < msg.when) {
Jeff Browne799cb72012-02-14 11:53:33 -0800160 // Next message is not ready. Set a timeout to wake up when it is ready.
Jeff Brown0f85ce32012-02-16 14:41:10 -0800161 nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
162 } else {
Jeff Browne799cb72012-02-14 11:53:33 -0800163 // Got a message.
Jeff Brown415d8c32010-10-05 15:35:37 -0700164 mBlocked = false;
Jeff Browne799cb72012-02-14 11:53:33 -0800165 if (prevMsg != null) {
166 prevMsg.next = msg.next;
167 } else {
168 mMessages = msg.next;
169 }
Jeff Brown415d8c32010-10-05 15:35:37 -0700170 msg.next = null;
Joe Onorato43a17652011-04-06 19:22:23 -0700171 if (false) Log.v("MessageQueue", "Returning message: " + msg);
Jeff Brown85c3fe42010-09-21 16:45:16 -0700172 msg.markInUse();
Jeff Browned739322010-09-21 15:14:14 -0700173 return msg;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 }
Jeff Brown0f85ce32012-02-16 14:41:10 -0800175 } else {
176 // No more messages.
177 nextPollTimeoutMillis = -1;
Jeff Browned739322010-09-21 15:14:14 -0700178 }
179
Jeff Brown024136f2013-04-11 19:21:32 -0700180 // Process the quit message now that all pending messages have been handled.
Jeff Brown013cf842013-09-06 16:24:36 -0700181 if (mQuitting) {
Jeff Brown024136f2013-04-11 19:21:32 -0700182 dispose();
183 return null;
184 }
185
Jeff Browne799cb72012-02-14 11:53:33 -0800186 // If first time idle, then get the number of idlers to run.
Jeff Brown0f85ce32012-02-16 14:41:10 -0800187 // Idle handles only run if the queue is empty or if the first message
188 // in the queue (possibly a barrier) is due to be handled in the future.
189 if (pendingIdleHandlerCount < 0
190 && (mMessages == null || now < mMessages.when)) {
Jeff Browned739322010-09-21 15:14:14 -0700191 pendingIdleHandlerCount = mIdleHandlers.size();
192 }
Jeff Browne799cb72012-02-14 11:53:33 -0800193 if (pendingIdleHandlerCount <= 0) {
Jeff Browned739322010-09-21 15:14:14 -0700194 // No idle handlers to run. Loop and wait some more.
Jeff Brown415d8c32010-10-05 15:35:37 -0700195 mBlocked = true;
Jeff Browned739322010-09-21 15:14:14 -0700196 continue;
197 }
198
199 if (mPendingIdleHandlers == null) {
200 mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
201 }
202 mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
203 }
204
205 // Run the idle handlers.
206 // We only ever reach this code block during the first iteration.
207 for (int i = 0; i < pendingIdleHandlerCount; i++) {
208 final IdleHandler idler = mPendingIdleHandlers[i];
209 mPendingIdleHandlers[i] = null; // release the reference to the handler
210
211 boolean keep = false;
212 try {
213 keep = idler.queueIdle();
214 } catch (Throwable t) {
215 Log.wtf("MessageQueue", "IdleHandler threw exception", t);
216 }
217
218 if (!keep) {
219 synchronized (this) {
220 mIdleHandlers.remove(idler);
221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 }
223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224
Jeff Browned739322010-09-21 15:14:14 -0700225 // Reset the idle handler count to 0 so we do not run them again.
226 pendingIdleHandlerCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227
Jeff Browned739322010-09-21 15:14:14 -0700228 // While calling an idle handler, a new message could have been delivered
229 // so go back and look again for a pending message without waiting.
230 nextPollTimeoutMillis = 0;
231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 }
233
Jeff Brown8b60e452013-04-18 15:17:48 -0700234 void quit(boolean safe) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800235 if (!mQuitAllowed) {
236 throw new RuntimeException("Main thread not allowed to quit.");
237 }
238
239 synchronized (this) {
Jeff Brown013cf842013-09-06 16:24:36 -0700240 if (mQuitting) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800241 return;
242 }
Jeff Brown013cf842013-09-06 16:24:36 -0700243 mQuitting = true;
Jeff Brown8b60e452013-04-18 15:17:48 -0700244
245 if (safe) {
246 removeAllFutureMessagesLocked();
247 } else {
248 removeAllMessagesLocked();
249 }
Jeff Brown013cf842013-09-06 16:24:36 -0700250
251 // We can assume mPtr != 0 because mQuitting was previously false.
252 nativeWake(mPtr);
Jeff Brown0f85ce32012-02-16 14:41:10 -0800253 }
Jeff Brown0f85ce32012-02-16 14:41:10 -0800254 }
255
Jeff Brown67fc67c2013-04-01 13:00:33 -0700256 int enqueueSyncBarrier(long when) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800257 // Enqueue a new sync barrier token.
258 // We don't need to wake the queue because the purpose of a barrier is to stall it.
259 synchronized (this) {
260 final int token = mNextBarrierToken++;
261 final Message msg = Message.obtain();
Jeff Brown5182c782013-10-15 20:31:52 -0700262 msg.when = when;
Jeff Brown0f85ce32012-02-16 14:41:10 -0800263 msg.arg1 = token;
264
265 Message prev = null;
266 Message p = mMessages;
267 if (when != 0) {
268 while (p != null && p.when <= when) {
269 prev = p;
270 p = p.next;
271 }
272 }
273 if (prev != null) { // invariant: p == prev.next
274 msg.next = p;
275 prev.next = msg;
276 } else {
277 msg.next = p;
278 mMessages = msg;
279 }
280 return token;
281 }
282 }
283
Jeff Brown67fc67c2013-04-01 13:00:33 -0700284 void removeSyncBarrier(int token) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800285 // Remove a sync barrier token from the queue.
286 // If the queue is no longer stalled by a barrier then wake it.
Jeff Brown0f85ce32012-02-16 14:41:10 -0800287 synchronized (this) {
288 Message prev = null;
289 Message p = mMessages;
290 while (p != null && (p.target != null || p.arg1 != token)) {
291 prev = p;
292 p = p.next;
293 }
294 if (p == null) {
295 throw new IllegalStateException("The specified message queue synchronization "
296 + " barrier token has not been posted or has already been removed.");
297 }
Jeff Brown013cf842013-09-06 16:24:36 -0700298 final boolean needWake;
Jeff Brown0f85ce32012-02-16 14:41:10 -0800299 if (prev != null) {
300 prev.next = p.next;
301 needWake = false;
302 } else {
303 mMessages = p.next;
304 needWake = mMessages == null || mMessages.target != null;
305 }
306 p.recycle();
Jeff Brown013cf842013-09-06 16:24:36 -0700307
308 // If the loop is quitting then it is already awake.
309 // We can assume mPtr != 0 when mQuitting is false.
310 if (needWake && !mQuitting) {
311 nativeWake(mPtr);
312 }
Jeff Brown0f85ce32012-02-16 14:41:10 -0800313 }
314 }
315
Jeff Brown67fc67c2013-04-01 13:00:33 -0700316 boolean enqueueMessage(Message msg, long when) {
Wink Savillea334e7c2010-08-24 10:56:30 -0700317 if (msg.isInUse()) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800318 throw new AndroidRuntimeException(msg + " This message is already in use.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 }
Jeff Brown0f85ce32012-02-16 14:41:10 -0800320 if (msg.target == null) {
321 throw new AndroidRuntimeException("Message must have a target.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 }
Jeff Brown0f85ce32012-02-16 14:41:10 -0800323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 synchronized (this) {
Jeff Brown013cf842013-09-06 16:24:36 -0700325 if (mQuitting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 RuntimeException e = new RuntimeException(
Jeff Brown0f85ce32012-02-16 14:41:10 -0800327 msg.target + " sending message to a Handler on a dead thread");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 Log.w("MessageQueue", e.getMessage(), e);
329 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 }
331
332 msg.when = when;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 Message p = mMessages;
Jeff Brown013cf842013-09-06 16:24:36 -0700334 boolean needWake;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 if (p == null || when == 0 || when < p.when) {
Jeff Browne799cb72012-02-14 11:53:33 -0800336 // New head, wake up the event queue if blocked.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 msg.next = p;
338 mMessages = msg;
Jeff Browne799cb72012-02-14 11:53:33 -0800339 needWake = mBlocked;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 } else {
Jeff Browne799cb72012-02-14 11:53:33 -0800341 // Inserted within the middle of the queue. Usually we don't have to wake
Jeff Brown0f85ce32012-02-16 14:41:10 -0800342 // up the event queue unless there is a barrier at the head of the queue
343 // and the message is the earliest asynchronous message in the queue.
344 needWake = mBlocked && p.target == null && msg.isAsynchronous();
345 Message prev;
346 for (;;) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 prev = p;
348 p = p.next;
Jeff Brown0f85ce32012-02-16 14:41:10 -0800349 if (p == null || when < p.when) {
350 break;
351 }
352 if (needWake && p.isAsynchronous()) {
353 needWake = false;
354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 }
Jeff Brown0f85ce32012-02-16 14:41:10 -0800356 msg.next = p; // invariant: p == prev.next
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 prev.next = msg;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 }
Jeff Brown013cf842013-09-06 16:24:36 -0700359
360 // We can assume mPtr != 0 because mQuitting is false.
361 if (needWake) {
362 nativeWake(mPtr);
363 }
Jeff Brown415d8c32010-10-05 15:35:37 -0700364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 return true;
366 }
367
Jeff Brown67fc67c2013-04-01 13:00:33 -0700368 boolean hasMessages(Handler h, int what, Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800369 if (h == null) {
370 return false;
371 }
372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 synchronized (this) {
374 Message p = mMessages;
Jeff Brown0f85ce32012-02-16 14:41:10 -0800375 while (p != null) {
376 if (p.target == h && p.what == what && (object == null || p.obj == object)) {
377 return true;
378 }
379 p = p.next;
380 }
381 return false;
382 }
383 }
384
Jeff Brown67fc67c2013-04-01 13:00:33 -0700385 boolean hasMessages(Handler h, Runnable r, Object object) {
Romain Guyba6be8a2012-04-23 18:22:09 -0700386 if (h == null) {
387 return false;
388 }
389
390 synchronized (this) {
391 Message p = mMessages;
392 while (p != null) {
393 if (p.target == h && p.callback == r && (object == null || p.obj == object)) {
394 return true;
395 }
396 p = p.next;
397 }
398 return false;
399 }
400 }
401
Dianne Hackbornefa92b22013-05-03 14:11:43 -0700402 boolean isIdling() {
Jeff Brown013cf842013-09-06 16:24:36 -0700403 synchronized (this) {
Jeff Brown5182c782013-10-15 20:31:52 -0700404 return isIdlingLocked();
Jeff Brown013cf842013-09-06 16:24:36 -0700405 }
Dianne Hackbornefa92b22013-05-03 14:11:43 -0700406 }
407
Jeff Brown5182c782013-10-15 20:31:52 -0700408 private boolean isIdlingLocked() {
409 // If the loop is quitting then it must not be idling.
410 // We can assume mPtr != 0 when mQuitting is false.
411 return !mQuitting && nativeIsIdling(mPtr);
412 }
413
Jeff Brown67fc67c2013-04-01 13:00:33 -0700414 void removeMessages(Handler h, int what, Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800415 if (h == null) {
416 return;
417 }
418
419 synchronized (this) {
420 Message p = mMessages;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421
422 // Remove all messages at front.
423 while (p != null && p.target == h && p.what == what
424 && (object == null || p.obj == object)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 Message n = p.next;
426 mMessages = n;
427 p.recycle();
428 p = n;
429 }
430
431 // Remove all messages after front.
432 while (p != null) {
433 Message n = p.next;
434 if (n != null) {
435 if (n.target == h && n.what == what
436 && (object == null || n.obj == object)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 Message nn = n.next;
438 n.recycle();
439 p.next = nn;
440 continue;
441 }
442 }
443 p = n;
444 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 }
446 }
447
Jeff Brown67fc67c2013-04-01 13:00:33 -0700448 void removeMessages(Handler h, Runnable r, Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800449 if (h == null || r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 return;
451 }
452
453 synchronized (this) {
454 Message p = mMessages;
455
456 // Remove all messages at front.
457 while (p != null && p.target == h && p.callback == r
458 && (object == null || p.obj == object)) {
459 Message n = p.next;
460 mMessages = n;
461 p.recycle();
462 p = n;
463 }
464
465 // Remove all messages after front.
466 while (p != null) {
467 Message n = p.next;
468 if (n != null) {
469 if (n.target == h && n.callback == r
470 && (object == null || n.obj == object)) {
471 Message nn = n.next;
472 n.recycle();
473 p.next = nn;
474 continue;
475 }
476 }
477 p = n;
478 }
479 }
480 }
481
Jeff Brown67fc67c2013-04-01 13:00:33 -0700482 void removeCallbacksAndMessages(Handler h, Object object) {
Jeff Brown0f85ce32012-02-16 14:41:10 -0800483 if (h == null) {
484 return;
485 }
486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 synchronized (this) {
488 Message p = mMessages;
489
490 // Remove all messages at front.
491 while (p != null && p.target == h
492 && (object == null || p.obj == object)) {
493 Message n = p.next;
494 mMessages = n;
495 p.recycle();
496 p = n;
497 }
498
499 // Remove all messages after front.
500 while (p != null) {
501 Message n = p.next;
502 if (n != null) {
503 if (n.target == h && (object == null || n.obj == object)) {
504 Message nn = n.next;
505 n.recycle();
506 p.next = nn;
507 continue;
508 }
509 }
510 p = n;
511 }
512 }
513 }
Jeff Brown8b60e452013-04-18 15:17:48 -0700514
515 private void removeAllMessagesLocked() {
516 Message p = mMessages;
517 while (p != null) {
518 Message n = p.next;
519 p.recycle();
520 p = n;
521 }
522 mMessages = null;
523 }
524
525 private void removeAllFutureMessagesLocked() {
526 final long now = SystemClock.uptimeMillis();
527 Message p = mMessages;
528 if (p != null) {
529 if (p.when > now) {
530 removeAllMessagesLocked();
531 } else {
532 Message n;
533 for (;;) {
534 n = p.next;
535 if (n == null) {
536 return;
537 }
538 if (n.when > now) {
539 break;
540 }
541 p = n;
542 }
543 p.next = null;
544 do {
545 p = n;
546 n = p.next;
547 p.recycle();
548 } while (n != null);
549 }
550 }
551 }
Jeff Brown5182c782013-10-15 20:31:52 -0700552
553 void dump(Printer pw, String prefix) {
554 synchronized (this) {
555 long now = SystemClock.uptimeMillis();
556 int n = 0;
557 for (Message msg = mMessages; msg != null; msg = msg.next) {
558 pw.println(prefix + "Message " + n + ": " + msg.toString(now));
559 n++;
560 }
561 pw.println(prefix + "(Total messages: " + n + ", idling=" + isIdlingLocked()
562 + ", quitting=" + mQuitting + ")");
563 }
564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565}