summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/CombinedMessageQueue/MessageQueue.java57
-rw-r--r--tests/utils/testutils/java/android/os/test/TestLooper.java26
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() {