From 6c2adc82cc3d2bf3527b54e3a92db281c05dadf2 Mon Sep 17 00:00:00 2001 From: fengjinlan Date: Mon, 3 Feb 2020 15:50:11 +0800 Subject: [PATCH] Add method in Handler to remove messages with equal object Bug: 142293357 Test: atest AudioDeviceBrokerTest Change-Id: Ibae80f5008df54f4ac8544abb4cc5863ea3db86d Merged-In: Ibae80f5008df54f4ac8544abb4cc5863ea3db86d Signed-off-by: fengjinlan --- core/java/android/os/Handler.java | 31 +++++++ core/java/android/os/MessageQueue.java | 119 +++++++++++++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index af776d154c8f2..24aaa583f542f 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -795,6 +795,17 @@ public class Handler { mQueue.removeMessages(this, what, object); } + /** + * Remove any pending posts of messages with code 'what' and whose obj is + * 'object' that are in the message queue. If object is null, + * all messages will be removed. + * + *@hide + */ + public final void removeEqualMessages(int what, @Nullable Object object) { + mQueue.removeEqualMessages(this, what, object); + } + /** * Remove any pending posts of callbacks and sent messages whose * obj is token. If token is null, @@ -804,6 +815,16 @@ public class Handler { mQueue.removeCallbacksAndMessages(this, token); } + /** + * Remove any pending posts of callbacks and sent messages whose + * obj is token. If token is null, + * all callbacks and messages will be removed. + * + *@hide + */ + public final void removeCallbacksAndEqualMessages(@Nullable Object token) { + mQueue.removeCallbacksAndEqualMessages(this, token); + } /** * Check if there are any pending posts of messages with code 'what' in * the message queue. @@ -828,6 +849,16 @@ public class Handler { return mQueue.hasMessages(this, what, object); } + /** + * Check if there are any pending posts of messages with code 'what' and + * whose obj is 'object' in the message queue. + * + *@hide + */ + public final boolean hasEqualMessages(int what, @Nullable Object object) { + return mQueue.hasEqualMessages(this, what, object); + } + /** * Check if there are any pending posts of messages with callback r in * the message queue. diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index a72795daf7e50..dfa5b26142f8c 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -617,6 +617,23 @@ public final class MessageQueue { } } + boolean hasEqualMessages(Handler h, int what, Object object) { + if (h == null) { + return false; + } + + synchronized (this) { + Message p = mMessages; + while (p != null) { + if (p.target == h && p.what == what && (object == null || object.equals(p.obj))) { + return true; + } + p = p.next; + } + return false; + } + } + @UnsupportedAppUsage boolean hasMessages(Handler h, Runnable r, Object object) { if (h == null) { @@ -686,6 +703,40 @@ public final class MessageQueue { } } + void removeEqualMessages(Handler h, int what, Object object) { + if (h == null) { + return; + } + + synchronized (this) { + Message p = mMessages; + + // Remove all messages at front. + while (p != null && p.target == h && p.what == what + && (object == null || object.equals(p.obj))) { + Message n = p.next; + mMessages = n; + p.recycleUnchecked(); + p = n; + } + + // Remove all messages after front. + while (p != null) { + Message n = p.next; + if (n != null) { + if (n.target == h && n.what == what + && (object == null || object.equals(n.obj))) { + Message nn = n.next; + n.recycleUnchecked(); + p.next = nn; + continue; + } + } + p = n; + } + } + } + void removeMessages(Handler h, Runnable r, Object object) { if (h == null || r == null) { return; @@ -720,6 +771,41 @@ public final class MessageQueue { } } + void removeEqualMessages(Handler h, Runnable r, Object object) { + if (h == null || r == null) { + return; + } + + synchronized (this) { + Message p = mMessages; + + // Remove all messages at front. + while (p != null && p.target == h && p.callback == r + && (object == null || object.equals(p.obj))) { + Message n = p.next; + mMessages = n; + p.recycleUnchecked(); + p = n; + } + + // Remove all messages after front. + while (p != null) { + Message n = p.next; + if (n != null) { + if (n.target == h && n.callback == r + && (object == null || object.equals(n.obj))) { + Message nn = n.next; + n.recycleUnchecked(); + p.next = nn; + continue; + } + } + p = n; + } + } + } + + void removeCallbacksAndMessages(Handler h, Object object) { if (h == null) { return; @@ -753,6 +839,39 @@ public final class MessageQueue { } } + void removeCallbacksAndEqualMessages(Handler h, Object object) { + if (h == null) { + return; + } + + synchronized (this) { + Message p = mMessages; + + // Remove all messages at front. + while (p != null && p.target == h + && (object == null || object.equals(p.obj))) { + Message n = p.next; + mMessages = n; + p.recycleUnchecked(); + p = n; + } + + // Remove all messages after front. + while (p != null) { + Message n = p.next; + if (n != null) { + if (n.target == h && (object == null || object.equals(n.obj))) { + Message nn = n.next; + n.recycleUnchecked(); + p.next = nn; + continue; + } + } + p = n; + } + } + } + private void removeAllMessagesLocked() { Message p = mMessages; while (p != null) {