diff options
| -rw-r--r-- | core/java/android/os/CombinedMessageQueue/MessageQueue.java | 57 | ||||
| -rw-r--r-- | tests/utils/testutils/java/android/os/test/TestLooper.java | 26 |
2 files changed, 54 insertions, 29 deletions
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java index 9806ab25745c..081ae6933544 100644 --- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java +++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java @@ -92,7 +92,9 @@ public final class MessageQueue { * system processes and provides a higher level of concurrency and higher enqueue throughput * than the legacy implementation. */ - private static boolean sForceConcurrent = false; + private static boolean sUseConcurrent; + + private static boolean sUseConcurrentInitialized = false; @RavenwoodRedirect private native static long nativeInit(); @@ -109,8 +111,9 @@ public final class MessageQueue { private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events); MessageQueue(boolean quitAllowed) { - if (!sForceConcurrent) { - sForceConcurrent = Process.myUid() < Process.FIRST_APPLICATION_UID; + if (!sUseConcurrentInitialized) { + sUseConcurrent = Process.myUid() < Process.FIRST_APPLICATION_UID; + sUseConcurrentInitialized = true; } mQuitAllowed = quitAllowed; mPtr = nativeInit(); @@ -154,7 +157,7 @@ public final class MessageQueue { * @return True if the looper is idle. */ public boolean isIdle() { - if (sForceConcurrent) { + if (sUseConcurrent) { final long now = SystemClock.uptimeMillis(); if (stackHasMessages(null, 0, null, null, now, mMatchDeliverableMessages, false)) { @@ -204,7 +207,7 @@ public final class MessageQueue { if (handler == null) { throw new NullPointerException("Can't add a null IdleHandler"); } - if (sForceConcurrent) { + if (sUseConcurrent) { synchronized (mIdleHandlersLock) { mIdleHandlers.add(handler); } @@ -225,7 +228,7 @@ public final class MessageQueue { * @param handler The IdleHandler to be removed. */ public void removeIdleHandler(@NonNull IdleHandler handler) { - if (sForceConcurrent) { + if (sUseConcurrent) { synchronized (mIdleHandlersLock) { mIdleHandlers.remove(handler); } @@ -248,7 +251,7 @@ public final class MessageQueue { * @hide */ public boolean isPolling() { - if (sForceConcurrent) { + if (sUseConcurrent) { // 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); @@ -299,7 +302,7 @@ public final class MessageQueue { throw new IllegalArgumentException("listener must not be null"); } - if (sForceConcurrent) { + if (sUseConcurrent) { synchronized (mFileDescriptorRecordsLock) { updateOnFileDescriptorEventListenerLocked(fd, events, listener); } @@ -327,7 +330,7 @@ public final class MessageQueue { if (fd == null) { throw new IllegalArgumentException("fd must not be null"); } - if (sForceConcurrent) { + if (sUseConcurrent) { synchronized (mFileDescriptorRecordsLock) { updateOnFileDescriptorEventListenerLocked(fd, 0, null); } @@ -384,7 +387,7 @@ public final class MessageQueue { final int oldWatchedEvents; final OnFileDescriptorEventListener listener; final int seq; - if (sForceConcurrent) { + if (sUseConcurrent) { synchronized (mFileDescriptorRecordsLock) { record = mFileDescriptorRecords.get(fd); if (record == null) { @@ -704,7 +707,7 @@ public final class MessageQueue { @UnsupportedAppUsage Message next() { - if (sForceConcurrent) { + if (sUseConcurrent) { return nextConcurrent(); } @@ -830,7 +833,7 @@ public final class MessageQueue { throw new IllegalStateException("Main thread not allowed to quit."); } - if (sForceConcurrent) { + if (sUseConcurrent) { synchronized (mIdleHandlersLock) { if (sQuitting.compareAndSet(this, false, true)) { if (safe) { @@ -894,7 +897,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 (sForceConcurrent) { + if (sUseConcurrent) { final int token = mNextBarrierTokenAtomic.getAndIncrement(); // b/376573804: apps and tests may expect to be able to use reflection @@ -987,7 +990,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 (sForceConcurrent) { + if (sUseConcurrent) { boolean removed; MessageNode first; final MatchBarrierToken matchBarrierToken = new MatchBarrierToken(token); @@ -1054,7 +1057,7 @@ public final class MessageQueue { throw new IllegalArgumentException("Message must have a target."); } - if (sForceConcurrent) { + if (sUseConcurrent) { if (msg.isInUse()) { throw new IllegalStateException(msg + " This message is already in use."); } @@ -1183,7 +1186,7 @@ public final class MessageQueue { if (h == null) { return false; } - if (sForceConcurrent) { + if (sUseConcurrent) { return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, false); } @@ -1215,7 +1218,7 @@ public final class MessageQueue { if (h == null) { return false; } - if (sForceConcurrent) { + if (sUseConcurrent) { return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals, false); @@ -1249,7 +1252,7 @@ public final class MessageQueue { if (h == null) { return false; } - if (sForceConcurrent) { + if (sUseConcurrent) { return findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, false); } @@ -1281,7 +1284,7 @@ public final class MessageQueue { if (h == null) { return false; } - if (sForceConcurrent) { + if (sUseConcurrent) { return findOrRemoveMessages(h, -1, null, null, 0, mMatchHandler, false); } synchronized (this) { @@ -1300,7 +1303,7 @@ public final class MessageQueue { if (h == null) { return; } - if (sForceConcurrent) { + if (sUseConcurrent) { findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, true); return; } @@ -1351,7 +1354,7 @@ public final class MessageQueue { return; } - if (sForceConcurrent) { + if (sUseConcurrent) { findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals, true); return; } @@ -1403,7 +1406,7 @@ public final class MessageQueue { return; } - if (sForceConcurrent) { + if (sUseConcurrent) { findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, true); return; } @@ -1466,7 +1469,7 @@ public final class MessageQueue { return; } - if (sForceConcurrent) { + if (sUseConcurrent) { findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObjectEquals, true); return; } @@ -1528,7 +1531,7 @@ public final class MessageQueue { return; } - if (sForceConcurrent) { + if (sUseConcurrent) { findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObject, true); return; } @@ -1590,7 +1593,7 @@ public final class MessageQueue { return; } - if (sForceConcurrent) { + if (sUseConcurrent) { findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObjectEquals, true); return; } @@ -1738,7 +1741,7 @@ public final class MessageQueue { @NeverCompile void dump(Printer pw, String prefix, Handler h) { - if (sForceConcurrent) { + if (sUseConcurrent) { long now = SystemClock.uptimeMillis(); int n = 0; @@ -1799,7 +1802,7 @@ public final class MessageQueue { @NeverCompile void dumpDebug(ProtoOutputStream proto, long fieldId) { - if (sForceConcurrent) { + if (sUseConcurrent) { final long messageQueueToken = proto.start(fieldId); StackNode node = (StackNode) sState.getVolatile(this); diff --git a/tests/utils/testutils/java/android/os/test/TestLooper.java b/tests/utils/testutils/java/android/os/test/TestLooper.java index a826646f69f3..e6eabd804294 100644 --- a/tests/utils/testutils/java/android/os/test/TestLooper.java +++ b/tests/utils/testutils/java/android/os/test/TestLooper.java @@ -90,17 +90,39 @@ 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); - ThreadLocal<Looper> threadLocalLooper = (ThreadLocal<Looper>) THREAD_LOCAL_LOOPER_FIELD - .get(null); + ThreadLocal<Looper> threadLocalLooper = + (ThreadLocal<Looper>) THREAD_LOCAL_LOOPER_FIELD.get(null); threadLocalLooper.set(mLooper); } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { 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); + } + } } public Looper getLooper() { |