summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Shai Barack <shayba@google.com> 2025-01-31 16:53:28 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-01-31 16:53:28 -0800
commitb652cb193092176cdc88d1268d5c9430d7a9aafa (patch)
treeeb235baa548a2a669b7c80eedee24a35c63fd2cd
parenta8ddc3595e3cc4f8596d5f5d22a854f16b26c98f (diff)
Revert "Reland "Remove MessageQueue reflection from TestLooper""
This reverts commit a8ddc3595e3cc4f8596d5f5d22a854f16b26c98f. Reason for revert: seems to still fail the same tests as b/393534402 in post-submit Change-Id: Ieecdf67d5d0fbf3bfbae3312005d5b95e0f0b55b
-rw-r--r--tests/utils/testutils/java/android/os/test/TestLooper.java183
1 files changed, 22 insertions, 161 deletions
diff --git a/tests/utils/testutils/java/android/os/test/TestLooper.java b/tests/utils/testutils/java/android/os/test/TestLooper.java
index 9f6c8b60eb7b..83d22d923c78 100644
--- a/tests/utils/testutils/java/android/os/test/TestLooper.java
+++ b/tests/utils/testutils/java/android/os/test/TestLooper.java
@@ -18,24 +18,18 @@ package android.os.test;
import static org.junit.Assert.assertTrue;
-import android.os.Build;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.os.SystemClock;
-import android.os.TestLooperManager;
import android.util.Log;
-import androidx.test.InstrumentationRegistry;
-
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.ArrayDeque;
-import java.util.Queue;
import java.util.concurrent.Executor;
/**
@@ -50,9 +44,7 @@ import java.util.concurrent.Executor;
* The Robolectric class also allows advancing time.
*/
public class TestLooper {
- private final Looper mLooper;
- private final TestLooperManager mTestLooperManager;
- private final Clock mClock;
+ protected final Looper mLooper;
private static final Constructor<Looper> LOOPER_CONSTRUCTOR;
private static final Field THREAD_LOCAL_LOOPER_FIELD;
@@ -62,27 +54,9 @@ public class TestLooper {
private static final Method MESSAGE_MARK_IN_USE_METHOD;
private static final String TAG = "TestLooper";
- private AutoDispatchThread mAutoDispatchThread;
+ private final Clock mClock;
- /**
- * Baklava introduces new {@link TestLooperManager} APIs that we can use instead of reflection.
- */
- private static boolean isAtLeastBaklava() {
- TestLooperManager tlm =
- InstrumentationRegistry.getInstrumentation()
- .acquireLooperManager(Looper.getMainLooper());
- try {
- Long unused = tlm.peekWhen();
- return true;
- } catch (NoSuchMethodError e) {
- return false;
- } finally {
- tlm.release();
- }
- // TODO(shayba): delete the above, uncomment the below.
- // SDK_INT has not yet ramped to Baklava in all 25Q2 builds.
- // return Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA;
- }
+ private AutoDispatchThread mAutoDispatchThread;
static {
try {
@@ -90,22 +64,14 @@ public class TestLooper {
LOOPER_CONSTRUCTOR.setAccessible(true);
THREAD_LOCAL_LOOPER_FIELD = Looper.class.getDeclaredField("sThreadLocal");
THREAD_LOCAL_LOOPER_FIELD.setAccessible(true);
-
- if (isAtLeastBaklava()) {
- MESSAGE_QUEUE_MESSAGES_FIELD = null;
- MESSAGE_NEXT_FIELD = null;
- MESSAGE_WHEN_FIELD = null;
- MESSAGE_MARK_IN_USE_METHOD = null;
- } else {
- MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages");
- MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true);
- MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
- MESSAGE_NEXT_FIELD.setAccessible(true);
- MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
- MESSAGE_WHEN_FIELD.setAccessible(true);
- MESSAGE_MARK_IN_USE_METHOD = Message.class.getDeclaredMethod("markInUse");
- MESSAGE_MARK_IN_USE_METHOD.setAccessible(true);
- }
+ MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages");
+ MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true);
+ MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
+ MESSAGE_NEXT_FIELD.setAccessible(true);
+ MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
+ MESSAGE_WHEN_FIELD.setAccessible(true);
+ MESSAGE_MARK_IN_USE_METHOD = Message.class.getDeclaredMethod("markInUse");
+ MESSAGE_MARK_IN_USE_METHOD.setAccessible(true);
} catch (NoSuchFieldException | NoSuchMethodException e) {
throw new RuntimeException("Failed to initialize TestLooper", e);
}
@@ -140,13 +106,6 @@ public class TestLooper {
throw new RuntimeException("Reflection error constructing or accessing looper", e);
}
- if (isAtLeastBaklava()) {
- mTestLooperManager =
- InstrumentationRegistry.getInstrumentation().acquireLooperManager(mLooper);
- } else {
- mTestLooperManager = null;
- }
-
mClock = clock;
}
@@ -158,72 +117,19 @@ public class TestLooper {
return new HandlerExecutor(new Handler(getLooper()));
}
- private Message getMessageLinkedListLegacy() {
+ private Message getMessageLinkedList() {
try {
MessageQueue queue = mLooper.getQueue();
return (Message) MESSAGE_QUEUE_MESSAGES_FIELD.get(queue);
} catch (IllegalAccessException e) {
throw new RuntimeException("Access failed in TestLooper: get - MessageQueue.mMessages",
- e);
+ e);
}
}
public void moveTimeForward(long milliSeconds) {
- if (isAtLeastBaklava()) {
- moveTimeForwardBaklava(milliSeconds);
- } else {
- moveTimeForwardLegacy(milliSeconds);
- }
- }
-
- private void moveTimeForwardBaklava(long milliSeconds) {
- // Drain all Messages from the queue.
- Queue<Message> messages = new ArrayDeque<>();
- while (true) {
- Message message = mTestLooperManager.poll();
- if (message == null) {
- break;
- }
-
- // Adjust the Message's delivery time.
- long newWhen = message.when - milliSeconds;
- if (newWhen < 0) {
- newWhen = 0;
- }
- message.when = newWhen;
- messages.add(message);
- }
-
- // Repost all Messages back to the queuewith a new time.
- while (true) {
- Message message = messages.poll();
- if (message == null) {
- break;
- }
-
- Runnable callback = message.getCallback();
- Handler handler = message.getTarget();
- long when = message.getWhen();
-
- // The Message cannot be re-enqueued because it is marked in use.
- // Make a copy of the Message and recycle the original.
- // This resets {@link Message#isInUse()} but retains all other content.
- {
- Message newMessage = Message.obtain();
- newMessage.copyFrom(message);
- newMessage.setCallback(callback);
- mTestLooperManager.recycle(message);
- message = newMessage;
- }
-
- // Send the Message back to its Handler to be re-enqueued.
- handler.sendMessageAtTime(message, when);
- }
- }
-
- private void moveTimeForwardLegacy(long milliSeconds) {
try {
- Message msg = getMessageLinkedListLegacy();
+ Message msg = getMessageLinkedList();
while (msg != null) {
long updatedWhen = msg.getWhen() - milliSeconds;
if (updatedWhen < 0) {
@@ -241,12 +147,12 @@ public class TestLooper {
return mClock.uptimeMillis();
}
- private Message messageQueueNextLegacy() {
+ private Message messageQueueNext() {
try {
long now = currentTime();
Message prevMsg = null;
- Message msg = getMessageLinkedListLegacy();
+ Message msg = getMessageLinkedList();
if (msg != null && msg.getTarget() == null) {
// Stalled by a barrier. Find the next asynchronous message in
// the queue.
@@ -279,46 +185,18 @@ public class TestLooper {
/**
* @return true if there are pending messages in the message queue
*/
- public boolean isIdle() {
- if (isAtLeastBaklava()) {
- return isIdleBaklava();
- } else {
- return isIdleLegacy();
- }
- }
-
- private boolean isIdleBaklava() {
- Long when = mTestLooperManager.peekWhen();
- return when != null && currentTime() >= when;
- }
+ public synchronized boolean isIdle() {
+ Message messageList = getMessageLinkedList();
- private synchronized boolean isIdleLegacy() {
- Message messageList = getMessageLinkedListLegacy();
return messageList != null && currentTime() >= messageList.getWhen();
}
/**
* @return the next message in the Looper's message queue or null if there is none
*/
- public Message nextMessage() {
- if (isAtLeastBaklava()) {
- return nextMessageBaklava();
- } else {
- return nextMessageLegacy();
- }
- }
-
- private Message nextMessageBaklava() {
- if (isIdle()) {
- return mTestLooperManager.poll();
- } else {
- return null;
- }
- }
-
- private synchronized Message nextMessageLegacy() {
+ public synchronized Message nextMessage() {
if (isIdle()) {
- return messageQueueNextLegacy();
+ return messageQueueNext();
} else {
return null;
}
@@ -328,26 +206,9 @@ public class TestLooper {
* Dispatch the next message in the queue
* Asserts that there is a message in the queue
*/
- public void dispatchNext() {
- if (isAtLeastBaklava()) {
- dispatchNextBaklava();
- } else {
- dispatchNextLegacy();
- }
- }
-
- private void dispatchNextBaklava() {
- assertTrue(isIdle());
- Message msg = mTestLooperManager.poll();
- if (msg == null) {
- return;
- }
- msg.getTarget().dispatchMessage(msg);
- }
-
- private synchronized void dispatchNextLegacy() {
+ public synchronized void dispatchNext() {
assertTrue(isIdle());
- Message msg = messageQueueNextLegacy();
+ Message msg = messageQueueNext();
if (msg == null) {
return;
}