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

Commit 1bedccbd authored by Arthur Hung's avatar Arthur Hung
Browse files

Revert "Introduce SurfaceFlinger Queued Transaction"

This reverts commit 3e95285e.

Reason for revert: broken test b/169245126

Bug: 169245126

Change-Id: I9d4b01619433a31ad8d8b2698926599359322e83
parent 3e95285e
Loading
Loading
Loading
Loading
+146 −145
Original line number Diff line number Diff line
@@ -1896,18 +1896,19 @@ void SurfaceFlinger::onMessageInvalidate(int64_t vsyncId, nsecs_t expectedVSyncT

bool SurfaceFlinger::handleMessageTransaction() {
    ATRACE_CALL();
    uint32_t transactionFlags = peekTransactionFlags();

    if (getTransactionFlags(eTransactionFlushNeeded)) {
        flushPendingTransactionQueues();
        flushTransactionQueue();
    }
    bool flushedATransaction = flushTransactionQueues();

    uint32_t transactionFlags = peekTransactionFlags();
    bool runHandleTransaction =
            (transactionFlags && (transactionFlags != eTransactionFlushNeeded)) || mForceTraversal;
            (transactionFlags && (transactionFlags != eTransactionFlushNeeded)) ||
            flushedATransaction ||
            mForceTraversal;

    if (runHandleTransaction) {
        handleTransaction(eTransactionMask);
    } else {
        getTransactionFlags(eTransactionFlushNeeded);
    }

    if (transactionFlushNeeded()) {
@@ -2776,6 +2777,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
        });
    }

    commitInputWindowCommands();
    commitTransaction();
}

@@ -2816,6 +2818,11 @@ void SurfaceFlinger::updateInputWindowInfo() {
                                                                     : nullptr);
}

void SurfaceFlinger::commitInputWindowCommands() {
    mInputWindowCommands.merge(mPendingInputWindowCommands);
    mPendingInputWindowCommands.clear();
}

void SurfaceFlinger::updateCursorAsync() {
    compositionengine::CompositionRefreshArgs refreshArgs;
    for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
@@ -3168,52 +3175,50 @@ void SurfaceFlinger::setTraversalNeeded() {
    mForceTraversal = true;
}

void SurfaceFlinger::flushPendingTransactionQueues() {
bool SurfaceFlinger::flushTransactionQueues() {
    // to prevent onHandleDestroyed from being called while the lock is held,
    // we must keep a copy of the transactions (specifically the composer
    // states) around outside the scope of the lock
    std::vector<const TransactionState> transactions;
    bool flushedATransaction = false;
    {
        Mutex::Autolock _l(mQueueLock);
        Mutex::Autolock _l(mStateLock);

        auto it = mPendingTransactionQueues.begin();
        while (it != mPendingTransactionQueues.end()) {
        auto it = mTransactionQueues.begin();
        while (it != mTransactionQueues.end()) {
            auto& [applyToken, transactionQueue] = *it;

            while (!transactionQueue.empty()) {
                const auto& transaction = transactionQueue.front();
                if (!transactionIsReadyToBeApplied(transaction.desiredPresentTime,
                                                   transaction.states)) {
                    setTransactionFlags(eTransactionFlushNeeded);
                    break;
                }
                transactions.push_back(transaction);
                applyTransactionState(transaction.states, transaction.displays, transaction.flags,
                                      mPendingInputWindowCommands, transaction.desiredPresentTime,
                                      transaction.buffer, transaction.postTime,
                                      transaction.privileged, transaction.hasListenerCallbacks,
                                      transaction.listenerCallbacks, transaction.originPID,
                                      transaction.originUID, /*isMainThread*/ true);
                transactionQueue.pop();
                flushedATransaction = true;
            }

            if (transactionQueue.empty()) {
                it = mPendingTransactionQueues.erase(it);
                it = mTransactionQueues.erase(it);
                mTransactionCV.broadcast();
            } else {
                it = std::next(it, 1);
            }
        }
    }

    {
        Mutex::Autolock _l(mStateLock);
        for (const auto& transaction : transactions) {
            applyTransactionState(transaction.states, transaction.displays, transaction.flags,
                                  mInputWindowCommands, transaction.desiredPresentTime,
                                  transaction.buffer, transaction.postTime, transaction.privileged,
                                  transaction.hasListenerCallbacks, transaction.listenerCallbacks,
                                  transaction.originPID, transaction.originUID);
        }
    }
    return flushedATransaction;
}

bool SurfaceFlinger::transactionFlushNeeded() {
    Mutex::Autolock _l(mQueueLock);
    return !mPendingTransactionQueues.empty();
    return !mTransactionQueues.empty();
}


@@ -3248,16 +3253,17 @@ status_t SurfaceFlinger::setTransactionState(
    ATRACE_CALL();

    const int64_t postTime = systemTime();

    bool privileged = callingThreadHasUnscopedSurfaceFlingerAccess();
    {
        Mutex::Autolock _l(mQueueLock);

    Mutex::Autolock _l(mStateLock);

    // If its TransactionQueue already has a pending TransactionState or if it is pending
        auto itr = mPendingTransactionQueues.find(applyToken);
    auto itr = mTransactionQueues.find(applyToken);
    // if this is an animation frame, wait until prior animation frame has
    // been applied by SF
    if (flags & eAnimation) {
            while (itr != mPendingTransactionQueues.end()) {
        while (itr != mTransactionQueues.end()) {
            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
            if (CC_UNLIKELY(err != NO_ERROR)) {
                ALOGW_IF(err == TIMED_OUT,
@@ -3265,21 +3271,11 @@ status_t SurfaceFlinger::setTransactionState(
                         "waiting for animation frame to apply");
                break;
            }
                itr = mPendingTransactionQueues.find(applyToken);
            itr = mTransactionQueues.find(applyToken);
        }
    }

        // TODO(b/159125966): Remove eEarlyWakeup completly as no client should use this flag
        if (flags & eEarlyWakeup) {
            ALOGW("eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]");
        }

        if (!privileged && (flags & (eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd))) {
            ALOGE("Only WindowManager is allowed to use eExplicitEarlyWakeup[Start|End] flags");
            flags &= ~(eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd);
        }

        const bool pendingTransactions = itr != mPendingTransactionQueues.end();
    const bool pendingTransactions = itr != mTransactionQueues.end();
    // Expected present time is computed and cached on invalidate, so it may be stale.
    if (!pendingTransactions) {
        mExpectedPresentTime = calculateExpectedPresentTime(systemTime());
@@ -3290,92 +3286,43 @@ status_t SurfaceFlinger::setTransactionState(
    const int originUID = ipc->getCallingUid();

    if (pendingTransactions || !transactionIsReadyToBeApplied(desiredPresentTime, states)) {
            mPendingTransactionQueues[applyToken].emplace(states, displays, flags,
                                                          inputWindowCommands, desiredPresentTime,
        mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
                                               uncacheBuffer, postTime, privileged,
                                                          hasListenerCallbacks, listenerCallbacks,
                                                          originPID, originUID);
            setTransactionFlags(eTransactionFlushNeeded);
            return NO_ERROR;
        }

        mTransactionQueue.emplace_back(states, displays, flags, inputWindowCommands,
                                       desiredPresentTime, uncacheBuffer, postTime, privileged,
                                               hasListenerCallbacks, listenerCallbacks, originPID,
                                               originUID);
        setTransactionFlags(eTransactionFlushNeeded);
        return NO_ERROR;
    }

    {
        Mutex::Autolock _l(mStateLock);

        const auto schedule = [](uint32_t flags) {
            if (flags & eEarlyWakeup) return TransactionSchedule::Early;
            if (flags & eExplicitEarlyWakeupEnd) return TransactionSchedule::EarlyEnd;
            if (flags & eExplicitEarlyWakeupStart) return TransactionSchedule::EarlyStart;
            return TransactionSchedule::Late;
        }(flags);

        // if this is a synchronous transaction, wait for it to take effect
        // before returning.
        const bool synchronous = flags & eSynchronous;
        const bool syncInput = inputWindowCommands.syncInputWindows;
        if (!synchronous && !syncInput) {
            setTransactionFlags(eTransactionFlushNeeded, schedule);
    applyTransactionState(states, displays, flags, inputWindowCommands, desiredPresentTime,
                          uncacheBuffer, postTime, privileged, hasListenerCallbacks,
                          listenerCallbacks, originPID, originUID, /*isMainThread*/ false);
    return NO_ERROR;
}

        if (synchronous) {
            mTransactionPending = true;
        }
        if (syncInput) {
            mPendingSyncInputWindows = true;
        }
        setTransactionFlags(eTransactionFlushNeeded, schedule);
void SurfaceFlinger::applyTransactionState(
        const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags,
        const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime,
        const client_cache_t& uncacheBuffer, const int64_t postTime, bool privileged,
        bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
        int originPID, int originUID, bool isMainThread) {
    uint32_t transactionFlags = 0;

        // applyTransactionState can be called by either the main SF thread or by
        // another process through setTransactionState.  While a given process may wish
        // to wait on synchronous transactions, the main SF thread should never
        // be blocked.  Therefore, we only wait if isMainThread is false.
        while (mTransactionPending || mPendingSyncInputWindows) {
    if (flags & eAnimation) {
        // For window updates that are part of an animation we must wait for
        // previous animation "frames" to be handled.
        while (!isMainThread && mAnimTransactionPending) {
            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
            if (CC_UNLIKELY(err != NO_ERROR)) {
                // just in case something goes wrong in SF, return to the
                // called after a few seconds.
                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
                mTransactionPending = false;
                mPendingSyncInputWindows = false;
                // caller after a few seconds.
                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
                        "waiting for previous animation frame");
                mAnimTransactionPending = false;
                break;
            }
        }
    }
    return NO_ERROR;
}

void SurfaceFlinger::flushTransactionQueue() {
    std::vector<TransactionState> transactionQueue;
    {
        Mutex::Autolock _l(mQueueLock);
        if (!mTransactionQueue.empty()) {
            transactionQueue.swap(mTransactionQueue);
        }
    }

    Mutex::Autolock _l(mStateLock);
    for (const auto& t : transactionQueue) {
        applyTransactionState(t.states, t.displays, t.flags, t.inputWindowCommands,
                              t.desiredPresentTime, t.buffer, t.postTime, t.privileged,
                              t.hasListenerCallbacks, t.listenerCallbacks, t.originPID,
                              t.originUID);
    }
}

void SurfaceFlinger::applyTransactionState(
        const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags,
        const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime,
        const client_cache_t& uncacheBuffer, const int64_t postTime, bool privileged,
        bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
        int32_t originPID, int32_t originUID) {
    uint32_t transactionFlags = 0;

    for (const DisplayState& display : displays) {
        transactionFlags |= setDisplayStateLocked(display);
@@ -3432,25 +3379,80 @@ void SurfaceFlinger::applyTransactionState(
        transactionFlags = eTransactionNeeded;
    }

    if (transactionFlags && mInterceptor->isEnabled()) {
        mInterceptor->saveTransaction(states, mCurrentState.displays, displays, flags, originPID,
                                      originUID);
    }

    // We are on the main thread, we are about to preform a traversal. Clear the traversal bit
    // so we don't have to wake up again next frame to preform an unnecessary traversal.
    if (transactionFlags & eTraversalNeeded) {
    // If we are on the main thread, we are about to preform a traversal. Clear the traversal bit
    // so we don't have to wake up again next frame to preform an uneeded traversal.
    if (isMainThread && (transactionFlags & eTraversalNeeded)) {
        transactionFlags = transactionFlags & (~eTraversalNeeded);
        mForceTraversal = true;
    }

    const auto schedule = [](uint32_t flags) {
        if (flags & eEarlyWakeup) return TransactionSchedule::Early;
        if (flags & eExplicitEarlyWakeupEnd) return TransactionSchedule::EarlyEnd;
        if (flags & eExplicitEarlyWakeupStart) return TransactionSchedule::EarlyStart;
        return TransactionSchedule::Late;
    }(flags);

    if (transactionFlags) {
        if (mInterceptor->isEnabled()) {
            mInterceptor->saveTransaction(states, mCurrentState.displays, displays, flags,
                                          originPID, originUID);
        }

        // TODO(b/159125966): Remove eEarlyWakeup completly as no client should use this flag
        if (flags & eEarlyWakeup) {
            ALOGW("eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]");
        }

        if (!privileged && (flags & (eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd))) {
            ALOGE("Only WindowManager is allowed to use eExplicitEarlyWakeup[Start|End] flags");
            flags &= ~(eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd);
        }

        // this triggers the transaction
        setTransactionFlags(transactionFlags);
        setTransactionFlags(transactionFlags, schedule);

        if (flags & eAnimation) {
            mAnimTransactionPending = true;
        }

        // if this is a synchronous transaction, wait for it to take effect
        // before returning.
        const bool synchronous = flags & eSynchronous;
        const bool syncInput = inputWindowCommands.syncInputWindows;
        if (!synchronous && !syncInput) {
            return;
        }

        if (synchronous) {
            mTransactionPending = true;
        }
        if (syncInput) {
            mPendingSyncInputWindows = true;
        }


        // applyTransactionState can be called by either the main SF thread or by
        // another process through setTransactionState.  While a given process may wish
        // to wait on synchronous transactions, the main SF thread should never
        // be blocked.  Therefore, we only wait if isMainThread is false.
        while (!isMainThread && (mTransactionPending || mPendingSyncInputWindows)) {
            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
            if (CC_UNLIKELY(err != NO_ERROR)) {
                // just in case something goes wrong in SF, return to the
                // called after a few seconds.
                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
                mTransactionPending = false;
                mPendingSyncInputWindows = false;
                break;
            }
        }
    } else {
        // Update VsyncModulator state machine even if transaction is not needed.
        if (schedule == TransactionSchedule::EarlyStart ||
            schedule == TransactionSchedule::EarlyEnd) {
            modulateVsync(&VsyncModulator::setTransactionSchedule, schedule);
        }
    }
}

@@ -3829,7 +3831,7 @@ uint32_t SurfaceFlinger::setClientStateLocked(
}

uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
    bool hasChanges = mInputWindowCommands.merge(inputWindowCommands);
    bool hasChanges = mPendingInputWindowCommands.merge(inputWindowCommands);
    return hasChanges ? eTraversalNeeded : 0;
}

@@ -4107,9 +4109,8 @@ void SurfaceFlinger::onInitializeDisplays() {
    d.width = 0;
    d.height = 0;
    displays.add(d);
    // This called on the main thread, apply it directly.
    applyTransactionState(state, displays, 0, mInputWindowCommands, -1, {}, systemTime(), true,
                          false, {}, getpid(), getuid());
    setTransactionState(state, displays, 0, nullptr, mPendingInputWindowCommands, -1, {}, false,
                        {});

    setPowerModeInternal(display, hal::PowerMode::ON);
    const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
@@ -5273,7 +5274,7 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r

void SurfaceFlinger::repaintEverything() {
    mRepaintEverything = true;
    setTransactionFlags(eTransactionNeeded);
    signalTransaction();
}

void SurfaceFlinger::repaintEverythingForHWC() {
+9 −13
Original line number Diff line number Diff line
@@ -433,15 +433,13 @@ private:
    struct TransactionState {
        TransactionState(const Vector<ComposerState>& composerStates,
                         const Vector<DisplayState>& displayStates, uint32_t transactionFlags,
                         const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
                         const client_cache_t& uncacheBuffer, int64_t postTime, bool privileged,
                         bool hasListenerCallbacks,
                         int64_t desiredPresentTime, const client_cache_t& uncacheBuffer,
                         int64_t postTime, bool privileged, bool hasListenerCallbacks,
                         std::vector<ListenerCallbacks> listenerCallbacks, int originPID,
                         int originUID)
              : states(composerStates),
                displays(displayStates),
                flags(transactionFlags),
                inputWindowCommands(inputWindowCommands),
                desiredPresentTime(desiredPresentTime),
                buffer(uncacheBuffer),
                postTime(postTime),
@@ -454,7 +452,6 @@ private:
        Vector<ComposerState> states;
        Vector<DisplayState> displays;
        uint32_t flags;
        InputWindowCommands inputWindowCommands;
        const int64_t desiredPresentTime;
        client_cache_t buffer;
        const int64_t postTime;
@@ -707,7 +704,6 @@ private:
    /*
     * Transactions
     */
    void flushTransactionQueue();
    void applyTransactionState(const Vector<ComposerState>& state,
                               const Vector<DisplayState>& displays, uint32_t flags,
                               const InputWindowCommands& inputWindowCommands,
@@ -715,9 +711,10 @@ private:
                               const client_cache_t& uncacheBuffer, const int64_t postTime,
                               bool privileged, bool hasListenerCallbacks,
                               const std::vector<ListenerCallbacks>& listenerCallbacks,
                               int32_t originPID, int32_t originUID) REQUIRES(mStateLock);
    // flush pending transaction that was presented after desiredPresentTime.
    void flushPendingTransactionQueues();
                               int originPID, int originUID, bool isMainThread = false)
            REQUIRES(mStateLock);
    // Returns true if at least one transaction was flushed
    bool flushTransactionQueues();
    // Returns true if there is at least one transaction that needs to be flushed
    bool transactionFlushNeeded();
    uint32_t getTransactionFlags(uint32_t flags);
@@ -1161,10 +1158,8 @@ private:
    uint32_t mTexturePoolSize = 0;
    std::vector<uint32_t> mTexturePool;

    mutable Mutex mQueueLock;
    std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash>
            mPendingTransactionQueues GUARDED_BY(mQueueLock);
    std::vector<TransactionState> mTransactionQueue GUARDED_BY(mQueueLock);
    std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash> mTransactionQueues;

    /*
     * Feature prototyping
     */
@@ -1241,6 +1236,7 @@ private:
    const float mEmulatedDisplayDensity;

    sp<os::IInputFlinger> mInputFlinger;
    InputWindowCommands mPendingInputWindowCommands GUARDED_BY(mStateLock);
    // Should only be accessed by the main thread.
    InputWindowCommands mInputWindowCommands;

+0 −3
Original line number Diff line number Diff line
@@ -68,9 +68,6 @@ public:
                                       Rect(displayState.layerStackSpaceRect), Rect(resolution));
                t.apply();
                SurfaceComposerClient::Transaction().apply(true);
                // wait for 3 vsyncs to ensure the buffer is latched.
                usleep(static_cast<int32_t>(1e6 / displayConfig.refreshRate) * 3);

                BufferItem item;
                itemConsumer->acquireBuffer(&item, 0, true);
                auto sc = std::make_unique<ScreenCapture>(item.mGraphicBuffer);
+2 −2
Original line number Diff line number Diff line
@@ -346,7 +346,7 @@ public:
        return mFlinger->SurfaceFlinger::getDisplayNativePrimaries(displayToken, primaries);
    }

    auto& getPendingTransactionQueue() { return mFlinger->mPendingTransactionQueues; }
    auto& getTransactionQueue() { return mFlinger->mTransactionQueues; }

    auto setTransactionState(const Vector<ComposerState>& states,
                             const Vector<DisplayState>& displays, uint32_t flags,
@@ -360,7 +360,7 @@ public:
                                             hasListenerCallbacks, listenerCallbacks);
    }

    auto flushPendingTransactionQueues() { return mFlinger->flushPendingTransactionQueues(); };
    auto flushTransactionQueues() { return mFlinger->flushTransactionQueues(); };

    auto onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
        return mFlinger->onTransact(code, data, reply, flags);
+10 −10
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ public:
    }

    void NotPlacedOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
        ASSERT_EQ(0, mFlinger.getPendingTransactionQueue().size());
        ASSERT_EQ(0, mFlinger.getTransactionQueue().size());
        // called in SurfaceFlinger::signalTransaction
        EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
        EXPECT_CALL(*mVSyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillOnce(Return(systemTime()));
@@ -146,12 +146,12 @@ public:
        } else {
            EXPECT_LE(returnedTime, applicationTime + s2ns(5));
        }
        auto transactionQueue = mFlinger.getPendingTransactionQueue();
        auto transactionQueue = mFlinger.getTransactionQueue();
        EXPECT_EQ(0, transactionQueue.size());
    }

    void PlaceOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
        ASSERT_EQ(0, mFlinger.getPendingTransactionQueue().size());
        ASSERT_EQ(0, mFlinger.getTransactionQueue().size());
        // called in SurfaceFlinger::signalTransaction
        EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);

@@ -172,12 +172,12 @@ public:
        nsecs_t returnedTime = systemTime();
        EXPECT_LE(returnedTime, applicationSentTime + s2ns(5));
        // This transaction should have been placed on the transaction queue
        auto transactionQueue = mFlinger.getPendingTransactionQueue();
        auto transactionQueue = mFlinger.getTransactionQueue();
        EXPECT_EQ(1, transactionQueue.size());
    }

    void BlockedByPriorTransaction(uint32_t flags, bool syncInputWindows) {
        ASSERT_EQ(0, mFlinger.getPendingTransactionQueue().size());
        ASSERT_EQ(0, mFlinger.getTransactionQueue().size());
        // called in SurfaceFlinger::signalTransaction
        nsecs_t time = systemTime();
        EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
@@ -222,7 +222,7 @@ public:
        }

        // check that there is one binder on the pending queue.
        auto transactionQueue = mFlinger.getPendingTransactionQueue();
        auto transactionQueue = mFlinger.getTransactionQueue();
        EXPECT_EQ(1, transactionQueue.size());

        auto& [applyToken, transactionStates] = *(transactionQueue.begin());
@@ -241,7 +241,7 @@ public:
};

TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
    ASSERT_EQ(0, mFlinger.getPendingTransactionQueue().size());
    ASSERT_EQ(0, mFlinger.getTransactionQueue().size());
    // called in SurfaceFlinger::signalTransaction
    EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);

@@ -257,7 +257,7 @@ TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
                                 transactionA.desiredPresentTime, transactionA.uncacheBuffer,
                                 mHasListenerCallbacks, mCallbacks);

    auto& transactionQueue = mFlinger.getPendingTransactionQueue();
    auto& transactionQueue = mFlinger.getTransactionQueue();
    ASSERT_EQ(1, transactionQueue.size());

    auto& [applyToken, transactionStates] = *(transactionQueue.begin());
@@ -275,9 +275,9 @@ TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
                                 empty.inputWindowCommands, empty.desiredPresentTime,
                                 empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks);

    // flush pending transaction queue should flush as desiredPresentTime has
    // flush transaction queue should flush as desiredPresentTime has
    // passed
    mFlinger.flushPendingTransactionQueues();
    mFlinger.flushTransactionQueues();

    EXPECT_EQ(0, transactionQueue.size());
}