Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6144a8e6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Make CombinedMessageQueue pick an implementation per instance" into main

parents 64be046f 125931a3
Loading
Loading
Loading
Loading
+26 −31
Original line number Diff line number Diff line
@@ -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);
+18 −0
Original line number Diff line number Diff line
@@ -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;
@@ -62,6 +63,14 @@ public class TestableLooper {
    private TestLooperManager mQueueWrapper;

    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);
@@ -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);
            }
        }
    }

    /**
+12 −22
Original line number Diff line number Diff line
@@ -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) {
        // If we are using CombinedMessageQueue, we need to disable concurrent mode for testing.
        try {
                messageQueueUseConcurrentField.set(null, previousUseConcurrentValue);
            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() {