diff options
| author | 2024-11-06 00:26:53 +0000 | |
|---|---|---|
| committer | 2024-11-06 00:26:53 +0000 | |
| commit | 6144a8e6317bd7fe23dc9543c2f7dec6d751a58c (patch) | |
| tree | e12bb43b0609238fec812a2921bf2230fbeca2c7 | |
| parent | 64be046f788fdc9b6235b66d33c811055898f81d (diff) | |
| parent | 125931a3c63dc54ac41b87f5c2452b525be0bcff (diff) | |
Merge "Make CombinedMessageQueue pick an implementation per instance" into main
3 files changed, 56 insertions, 53 deletions
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java index 66f4198ad31c..6cfbf4ebf661 100644 --- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java +++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java @@ -93,9 +93,7 @@ public final class MessageQueue { * system processes and provides a higher level of concurrency and higher enqueue throughput * than the legacy implementation. */ - private static boolean sUseConcurrent; - - private static boolean sUseConcurrentInitialized = false; + private boolean mUseConcurrent; @RavenwoodRedirect private native static long nativeInit(); @@ -112,10 +110,7 @@ public final class MessageQueue { private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events); MessageQueue(boolean quitAllowed) { - if (!sUseConcurrentInitialized) { - sUseConcurrent = UserHandle.isCore(Process.myUid()); - sUseConcurrentInitialized = true; - } + mUseConcurrent = UserHandle.isCore(Process.myUid()); mQuitAllowed = quitAllowed; mPtr = nativeInit(); } @@ -158,7 +153,7 @@ public final class MessageQueue { * @return True if the looper is idle. */ public boolean isIdle() { - if (sUseConcurrent) { + if (mUseConcurrent) { final long now = SystemClock.uptimeMillis(); if (stackHasMessages(null, 0, null, null, now, mMatchDeliverableMessages, false)) { @@ -208,7 +203,7 @@ public final class MessageQueue { if (handler == null) { throw new NullPointerException("Can't add a null IdleHandler"); } - if (sUseConcurrent) { + if (mUseConcurrent) { synchronized (mIdleHandlersLock) { mIdleHandlers.add(handler); } @@ -229,7 +224,7 @@ public final class MessageQueue { * @param handler The IdleHandler to be removed. */ public void removeIdleHandler(@NonNull IdleHandler handler) { - if (sUseConcurrent) { + if (mUseConcurrent) { synchronized (mIdleHandlersLock) { mIdleHandlers.remove(handler); } @@ -252,7 +247,7 @@ public final class MessageQueue { * @hide */ public boolean isPolling() { - if (sUseConcurrent) { + if (mUseConcurrent) { // If the loop is quitting then it must not be idling. // We can assume mPtr != 0 when sQuitting is false. return !((boolean) sQuitting.getVolatile(this)) && nativeIsPolling(mPtr); @@ -303,7 +298,7 @@ public final class MessageQueue { throw new IllegalArgumentException("listener must not be null"); } - if (sUseConcurrent) { + if (mUseConcurrent) { synchronized (mFileDescriptorRecordsLock) { updateOnFileDescriptorEventListenerLocked(fd, events, listener); } @@ -331,7 +326,7 @@ public final class MessageQueue { if (fd == null) { throw new IllegalArgumentException("fd must not be null"); } - if (sUseConcurrent) { + if (mUseConcurrent) { synchronized (mFileDescriptorRecordsLock) { updateOnFileDescriptorEventListenerLocked(fd, 0, null); } @@ -388,7 +383,7 @@ public final class MessageQueue { final int oldWatchedEvents; final OnFileDescriptorEventListener listener; final int seq; - if (sUseConcurrent) { + if (mUseConcurrent) { synchronized (mFileDescriptorRecordsLock) { record = mFileDescriptorRecords.get(fd); if (record == null) { @@ -708,7 +703,7 @@ public final class MessageQueue { @UnsupportedAppUsage Message next() { - if (sUseConcurrent) { + if (mUseConcurrent) { return nextConcurrent(); } @@ -834,7 +829,7 @@ public final class MessageQueue { throw new IllegalStateException("Main thread not allowed to quit."); } - if (sUseConcurrent) { + if (mUseConcurrent) { synchronized (mIdleHandlersLock) { if (sQuitting.compareAndSet(this, false, true)) { if (safe) { @@ -898,7 +893,7 @@ public final class MessageQueue { private int postSyncBarrier(long when) { // Enqueue a new sync barrier token. // We don't need to wake the queue because the purpose of a barrier is to stall it. - if (sUseConcurrent) { + if (mUseConcurrent) { final int token = mNextBarrierTokenAtomic.getAndIncrement(); // b/376573804: apps and tests may expect to be able to use reflection @@ -991,7 +986,7 @@ public final class MessageQueue { public void removeSyncBarrier(int token) { // Remove a sync barrier token from the queue. // If the queue is no longer stalled by a barrier then wake it. - if (sUseConcurrent) { + if (mUseConcurrent) { boolean removed; MessageNode first; final MatchBarrierToken matchBarrierToken = new MatchBarrierToken(token); @@ -1058,7 +1053,7 @@ public final class MessageQueue { throw new IllegalArgumentException("Message must have a target."); } - if (sUseConcurrent) { + if (mUseConcurrent) { if (msg.isInUse()) { throw new IllegalStateException(msg + " This message is already in use."); } @@ -1187,7 +1182,7 @@ public final class MessageQueue { if (h == null) { return false; } - if (sUseConcurrent) { + if (mUseConcurrent) { return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, false); } @@ -1219,7 +1214,7 @@ public final class MessageQueue { if (h == null) { return false; } - if (sUseConcurrent) { + if (mUseConcurrent) { return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals, false); @@ -1253,7 +1248,7 @@ public final class MessageQueue { if (h == null) { return false; } - if (sUseConcurrent) { + if (mUseConcurrent) { return findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, false); } @@ -1285,7 +1280,7 @@ public final class MessageQueue { if (h == null) { return false; } - if (sUseConcurrent) { + if (mUseConcurrent) { return findOrRemoveMessages(h, -1, null, null, 0, mMatchHandler, false); } synchronized (this) { @@ -1304,7 +1299,7 @@ public final class MessageQueue { if (h == null) { return; } - if (sUseConcurrent) { + if (mUseConcurrent) { findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, true); return; } @@ -1355,7 +1350,7 @@ public final class MessageQueue { return; } - if (sUseConcurrent) { + if (mUseConcurrent) { findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals, true); return; } @@ -1407,7 +1402,7 @@ public final class MessageQueue { return; } - if (sUseConcurrent) { + if (mUseConcurrent) { findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, true); return; } @@ -1470,7 +1465,7 @@ public final class MessageQueue { return; } - if (sUseConcurrent) { + if (mUseConcurrent) { findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObjectEquals, true); return; } @@ -1532,7 +1527,7 @@ public final class MessageQueue { return; } - if (sUseConcurrent) { + if (mUseConcurrent) { findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObject, true); return; } @@ -1594,7 +1589,7 @@ public final class MessageQueue { return; } - if (sUseConcurrent) { + if (mUseConcurrent) { findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObjectEquals, true); return; } @@ -1742,7 +1737,7 @@ public final class MessageQueue { @NeverCompile void dump(Printer pw, String prefix, Handler h) { - if (sUseConcurrent) { + if (mUseConcurrent) { long now = SystemClock.uptimeMillis(); int n = 0; @@ -1803,7 +1798,7 @@ public final class MessageQueue { @NeverCompile void dumpDebug(ProtoOutputStream proto, long fieldId) { - if (sUseConcurrent) { + if (mUseConcurrent) { final long messageQueueToken = proto.start(fieldId); StackNode node = (StackNode) sState.getVolatile(this); diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java index be5c84c0353c..ac96ef28f501 100644 --- a/tests/testables/src/android/testing/TestableLooper.java +++ b/tests/testables/src/android/testing/TestableLooper.java @@ -53,6 +53,7 @@ public class TestableLooper { private static final Field MESSAGE_QUEUE_MESSAGES_FIELD; private static final Field MESSAGE_NEXT_FIELD; private static final Field MESSAGE_WHEN_FIELD; + private static Field MESSAGE_QUEUE_USE_CONCURRENT_FIELD = null; private Looper mLooper; private MessageQueue mQueue; @@ -63,6 +64,14 @@ public class TestableLooper { static { try { + MESSAGE_QUEUE_USE_CONCURRENT_FIELD = + MessageQueue.class.getDeclaredField("mUseConcurrent"); + MESSAGE_QUEUE_USE_CONCURRENT_FIELD.setAccessible(true); + } catch (NoSuchFieldException ignored) { + // Ignore - maybe this is not CombinedMessageQueue? + } + + try { MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages"); MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true); MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next"); @@ -146,6 +155,15 @@ public class TestableLooper { mLooper = l; mQueue = mLooper.getQueue(); mHandler = new Handler(mLooper); + + // If we are using CombinedMessageQueue, we need to disable concurrent mode for testing. + if (MESSAGE_QUEUE_USE_CONCURRENT_FIELD != null) { + try { + MESSAGE_QUEUE_USE_CONCURRENT_FIELD.set(mQueue, false); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } } /** diff --git a/tests/utils/testutils/java/android/os/test/TestLooper.java b/tests/utils/testutils/java/android/os/test/TestLooper.java index e6eabd804294..1bcfaf60857d 100644 --- a/tests/utils/testutils/java/android/os/test/TestLooper.java +++ b/tests/utils/testutils/java/android/os/test/TestLooper.java @@ -90,20 +90,6 @@ public class TestLooper { * and call {@link #dispatchAll()}. */ public TestLooper(Clock clock) { - Field messageQueueUseConcurrentField = null; - boolean previousUseConcurrentValue = false; - try { - messageQueueUseConcurrentField = MessageQueue.class.getDeclaredField("sUseConcurrent"); - messageQueueUseConcurrentField.setAccessible(true); - previousUseConcurrentValue = messageQueueUseConcurrentField.getBoolean(null); - // If we are using CombinedMessageQueue, we need to disable concurrent mode for testing. - messageQueueUseConcurrentField.set(null, false); - } catch (NoSuchFieldException e) { - // Ignore - maybe this is not CombinedMessageQueue? - } catch (IllegalAccessException e) { - throw new RuntimeException("Reflection error constructing or accessing looper", e); - } - try { mLooper = LOOPER_CONSTRUCTOR.newInstance(false); @@ -114,15 +100,19 @@ public class TestLooper { throw new RuntimeException("Reflection error constructing or accessing looper", e); } - mClock = clock; - - if (messageQueueUseConcurrentField != null) { - try { - messageQueueUseConcurrentField.set(null, previousUseConcurrentValue); - } catch (IllegalAccessException e) { - throw new RuntimeException("Reflection error constructing or accessing looper", e); - } + // If we are using CombinedMessageQueue, we need to disable concurrent mode for testing. + try { + Field messageQueueUseConcurrentField = + MessageQueue.class.getDeclaredField("mUseConcurrent"); + messageQueueUseConcurrentField.setAccessible(true); + messageQueueUseConcurrentField.set(mLooper.getQueue(), false); + } catch (NoSuchFieldException e) { + // Ignore - maybe this is not CombinedMessageQueue? + } catch (IllegalAccessException e) { + throw new RuntimeException("Reflection error constructing or accessing looper", e); } + + mClock = clock; } public Looper getLooper() { |