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

Commit e5123a62 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 9474727 from b567cd17 to tm-qpr3-release

Change-Id: I32a27af550391f8844b9dc589f3e03d497c4cba9
parents e0b62b31 b567cd17
Loading
Loading
Loading
Loading
+27 −53
Original line number Diff line number Diff line
@@ -480,20 +480,18 @@ void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId,
    mSyncedFrameNumbers.erase(callbackId.framenumber);
}

void BLASTBufferQueue::acquireNextBufferLocked(
status_t BLASTBufferQueue::acquireNextBufferLocked(
        const std::optional<SurfaceComposerClient::Transaction*> transaction) {
    // If the next transaction is set, we want to guarantee the our acquire will not fail, so don't
    // include the extra buffer when checking if we can acquire the next buffer.
    const bool includeExtraAcquire = !transaction;
    const bool maxAcquired = maxBuffersAcquired(includeExtraAcquire);
    if (mNumFrameAvailable == 0 || maxAcquired) {
        BQA_LOGV("Can't process next buffer maxBuffersAcquired=%s", boolToString(maxAcquired));
        return;
    if (mNumFrameAvailable == 0) {
        BQA_LOGV("Can't process next buffer. No available frames");
        return NOT_ENOUGH_DATA;
    }

    if (mSurfaceControl == nullptr) {
        BQA_LOGE("ERROR : surface control is null");
        return;
        return NAME_NOT_FOUND;
    }

    SurfaceComposerClient::Transaction localTransaction;
@@ -510,10 +508,10 @@ void BLASTBufferQueue::acquireNextBufferLocked(
            mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false);
    if (status == BufferQueue::NO_BUFFER_AVAILABLE) {
        BQA_LOGV("Failed to acquire a buffer, err=NO_BUFFER_AVAILABLE");
        return;
        return status;
    } else if (status != OK) {
        BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str());
        return;
        return status;
    }

    auto buffer = bufferItem.mGraphicBuffer;
@@ -523,7 +521,7 @@ void BLASTBufferQueue::acquireNextBufferLocked(
    if (buffer == nullptr) {
        mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
        BQA_LOGE("Buffer was empty");
        return;
        return BAD_VALUE;
    }

    if (rejectBuffer(bufferItem)) {
@@ -532,8 +530,7 @@ void BLASTBufferQueue::acquireNextBufferLocked(
                 mSize.width, mSize.height, mRequestedSize.width, mRequestedSize.height,
                 buffer->getWidth(), buffer->getHeight(), bufferItem.mTransform);
        mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
        acquireNextBufferLocked(transaction);
        return;
        return acquireNextBufferLocked(transaction);
    }

    mNumAcquired++;
@@ -621,6 +618,7 @@ void BLASTBufferQueue::acquireNextBufferLocked(
             bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp ? "(auto)" : "",
             static_cast<uint32_t>(mPendingTransactions.size()), bufferItem.mGraphicBuffer->getId(),
             bufferItem.mAutoRefresh ? " mAutoRefresh" : "", bufferItem.mTransform);
    return OK;
}

Rect BLASTBufferQueue::computeCrop(const BufferItem& item) {
@@ -643,31 +641,6 @@ void BLASTBufferQueue::acquireAndReleaseBuffer() {
    mBufferItemConsumer->releaseBuffer(bufferItem, bufferItem.mFence);
}

void BLASTBufferQueue::flushAndWaitForFreeBuffer(std::unique_lock<std::mutex>& lock) {
    if (!mSyncedFrameNumbers.empty() && mNumFrameAvailable > 0) {
        // We are waiting on a previous sync's transaction callback so allow another sync
        // transaction to proceed.
        //
        // We need to first flush out the transactions that were in between the two syncs.
        // We do this by merging them into mSyncTransaction so any buffer merging will get
        // a release callback invoked. The release callback will be async so we need to wait
        // on max acquired to make sure we have the capacity to acquire another buffer.
        if (maxBuffersAcquired(false /* includeExtraAcquire */)) {
            BQA_LOGD("waiting to flush shadow queue...");
            mCallbackCV.wait(lock);
        }
        while (mNumFrameAvailable > 0) {
            // flush out the shadow queue
            acquireAndReleaseBuffer();
        }
    }

    while (maxBuffersAcquired(false /* includeExtraAcquire */)) {
        BQA_LOGD("waiting for free buffer.");
        mCallbackCV.wait(lock);
    }
}

void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
    std::function<void(SurfaceComposerClient::Transaction*)> prevCallback = nullptr;
    SurfaceComposerClient::Transaction* prevTransaction = nullptr;
@@ -680,7 +653,6 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
        BQA_LOGV("onFrameAvailable-start syncTransactionSet=%s", boolToString(syncTransactionSet));

        if (syncTransactionSet) {
            bool mayNeedToWaitForBuffer = true;
            // If we are going to re-use the same mSyncTransaction, release the buffer that may
            // already be set in the Transaction. This is to allow us a free slot early to continue
            // processing a new buffer.
@@ -691,14 +663,20 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
                             bufferData->frameNumber);
                    releaseBuffer(bufferData->generateReleaseCallbackId(),
                                  bufferData->acquireFence);
                    // Because we just released a buffer, we know there's no need to wait for a free
                    // buffer.
                    mayNeedToWaitForBuffer = false;
                }
            }

            if (mayNeedToWaitForBuffer) {
                flushAndWaitForFreeBuffer(_lock);
            if (waitForTransactionCallback) {
                // We are waiting on a previous sync's transaction callback so allow another sync
                // transaction to proceed.
                //
                // We need to first flush out the transactions that were in between the two syncs.
                // We do this by merging them into mSyncTransaction so any buffer merging will get
                // a release callback invoked.
                while (mNumFrameAvailable > 0) {
                    // flush out the shadow queue
                    acquireAndReleaseBuffer();
                }
            }
        }

@@ -714,7 +692,12 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
                 item.mFrameNumber, boolToString(syncTransactionSet));

        if (syncTransactionSet) {
            acquireNextBufferLocked(mSyncTransaction);
            // If there's no available buffer and we're in a sync transaction, we need to wait
            // instead of returning since we guarantee a buffer will be acquired for the sync.
            while (acquireNextBufferLocked(mSyncTransaction) == BufferQueue::NO_BUFFER_AVAILABLE) {
                BQA_LOGD("waiting for available buffer");
                mCallbackCV.wait(_lock);
            }

            // Only need a commit callback when syncing to ensure the buffer that's synced has been
            // sent to SF
@@ -824,15 +807,6 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) {
    return mSize != bufferSize;
}

// Check if we have acquired the maximum number of buffers.
// Consumer can acquire an additional buffer if that buffer is not droppable. Set
// includeExtraAcquire is true to include this buffer to the count. Since this depends on the state
// of the buffer, the next acquire may return with NO_BUFFER_AVAILABLE.
bool BLASTBufferQueue::maxBuffersAcquired(bool includeExtraAcquire) const {
    int maxAcquiredBuffers = mMaxAcquiredBuffers + (includeExtraAcquire ? 2 : 1);
    return mNumAcquired >= maxAcquiredBuffers;
}

class BBQSurface : public Surface {
private:
    std::mutex mMutex;
+1 −3
Original line number Diff line number Diff line
@@ -136,12 +136,11 @@ private:
    void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
                           sp<IGraphicBufferConsumer>* outConsumer);

    void acquireNextBufferLocked(
    status_t acquireNextBufferLocked(
            const std::optional<SurfaceComposerClient::Transaction*> transaction) REQUIRES(mMutex);
    Rect computeCrop(const BufferItem& item) REQUIRES(mMutex);
    // Return true if we need to reject the buffer based on the scaling mode and the buffer size.
    bool rejectBuffer(const BufferItem& item) REQUIRES(mMutex);
    bool maxBuffersAcquired(bool includeExtraAcquire) const REQUIRES(mMutex);
    static PixelFormat convertBufferFormat(PixelFormat& format);
    void mergePendingTransactions(SurfaceComposerClient::Transaction* t, uint64_t frameNumber)
            REQUIRES(mMutex);
@@ -150,7 +149,6 @@ private:
    void acquireAndReleaseBuffer() REQUIRES(mMutex);
    void releaseBuffer(const ReleaseCallbackId& callbackId, const sp<Fence>& releaseFence)
            REQUIRES(mMutex);
    void flushAndWaitForFreeBuffer(std::unique_lock<std::mutex>& lock);

    std::string mName;
    // Represents the queued buffer count from buffer queue,
+139 −45
Original line number Diff line number Diff line
@@ -2196,8 +2196,31 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
            // Update the temporary touch state.
            BitSet32 pointerIds;
            pointerIds.markBit(entry.pointerProperties[pointerIndex].id);

            tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds);

            // If this is the pointer going down and the touched window has a wallpaper
            // then also add the touched wallpaper windows so they are locked in for the duration
            // of the touch gesture.
            // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
            // engine only supports touch events.  We would need to add a mechanism similar
            // to View.onGenericMotionEvent to enable wallpapers to handle these events.
            if (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
                maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
                if ((targetFlags & InputTarget::FLAG_FOREGROUND) &&
                    windowHandle->getInfo()->inputConfig.test(
                            gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
                    sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle);
                    if (wallpaper != nullptr) {
                        int32_t wallpaperFlags = InputTarget::FLAG_WINDOW_IS_OBSCURED |
                                InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
                                InputTarget::FLAG_DISPATCH_AS_IS;
                        if (isSplit) {
                            wallpaperFlags |= InputTarget::FLAG_SPLIT;
                        }
                        tempTouchState.addOrUpdateWindow(wallpaper, wallpaperFlags, pointerIds);
                    }
                }
            }
        }
    } else {
        /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
@@ -2274,6 +2297,10 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
                BitSet32 pointerIds;
                pointerIds.markBit(entry.pointerProperties[0].id);
                tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);

                // Check if the wallpaper window should deliver the corresponding event.
                slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
                                   tempTouchState, pointerIds);
            }
        }

@@ -2379,39 +2406,6 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
        }
    }

    // If this is the first pointer going down and the touched window has a wallpaper
    // then also add the touched wallpaper windows so they are locked in for the duration
    // of the touch gesture.
    // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
    // engine only supports touch events.  We would need to add a mechanism similar
    // to View.onGenericMotionEvent to enable wallpapers to handle these events.
    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
        sp<WindowInfoHandle> foregroundWindowHandle =
                tempTouchState.getFirstForegroundWindowHandle();
        if (foregroundWindowHandle &&
            foregroundWindowHandle->getInfo()->inputConfig.test(
                    WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
            const std::vector<sp<WindowInfoHandle>>& windowHandles =
                    getWindowHandlesLocked(displayId);
            for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
                const WindowInfo* info = windowHandle->getInfo();
                if (info->displayId == displayId &&
                    windowHandle->getInfo()->inputConfig.test(
                            WindowInfo::InputConfig::IS_WALLPAPER)) {
                    BitSet32 pointerIds;
                    pointerIds.markBit(entry.pointerProperties[0].id);
                    tempTouchState
                            .addOrUpdateWindow(windowHandle,
                                               InputTarget::FLAG_WINDOW_IS_OBSCURED |
                                                       InputTarget::
                                                               FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
                                                       InputTarget::FLAG_DISPATCH_AS_IS,
                                               pointerIds);
                }
            }
        }
    }

    // Success!  Output targets.
    injectionResult = InputEventInjectionResult::SUCCEEDED;

@@ -3685,7 +3679,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
}

void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
        const sp<Connection>& connection) {
        const sp<Connection>& connection, int32_t targetFlags) {
    if (connection->status == Connection::Status::BROKEN) {
        return;
    }
@@ -3713,7 +3707,7 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
        target.globalScaleFactor = windowInfo->globalScaleFactor;
    }
    target.inputChannel = connection->inputChannel;
    target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
    target.flags = targetFlags;

    for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
        switch (downEventEntry->type) {
@@ -3744,6 +3738,16 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
    startDispatchCycleLocked(currentTime, connection);
}

void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
        const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options) {
    if (windowHandle != nullptr) {
        sp<Connection> wallpaperConnection = getConnectionLocked(windowHandle->getToken());
        if (wallpaperConnection != nullptr) {
            synthesizeCancelationEventsForConnectionLocked(wallpaperConnection, options);
        }
    }
}

std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
        const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
    ALOG_ASSERT(pointerIds.value != 0);
@@ -4762,14 +4766,7 @@ void InputDispatcher::setInputWindowsLocked(
                        touchedWindow.windowHandle->getInfo()->inputConfig.test(
                                gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
                        sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
                        if (wallpaper != nullptr) {
                            sp<Connection> wallpaperConnection =
                                    getConnectionLocked(wallpaper->getToken());
                            if (wallpaperConnection != nullptr) {
                                synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
                                                                               options);
                            }
                        }
                        synthesizeCancelationEventsForWindowLocked(wallpaper, options);
                    }
                }
                state.windows.erase(state.windows.begin() + i);
@@ -5082,6 +5079,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<
        // Erase old window.
        int32_t oldTargetFlags = touchedWindow->targetFlags;
        BitSet32 pointerIds = touchedWindow->pointerIds;
        sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
        state->removeWindowByToken(fromToken);

        // Add new window.
@@ -5113,7 +5111,10 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<
                    options(CancelationOptions::CANCEL_POINTER_EVENTS,
                            "transferring touch focus from this window to another window");
            synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
            synthesizePointerDownEventsForConnectionLocked(toConnection);
            synthesizePointerDownEventsForConnectionLocked(toConnection, newTargetFlags);
            // Check if the wallpaper window should deliver the corresponding event.
            transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
                                   *state, pointerIds);
        }

        if (DEBUG_FOCUS) {
@@ -6398,4 +6399,97 @@ void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanosecon
    mMonitorDispatchingTimeout = timeout;
}

void InputDispatcher::slipWallpaperTouch(int32_t targetFlags,
                                         const sp<WindowInfoHandle>& oldWindowHandle,
                                         const sp<WindowInfoHandle>& newWindowHandle,
                                         TouchState& state, const BitSet32& pointerIds) {
    const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
            gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
    const bool newHasWallpaper = (targetFlags & InputTarget::FLAG_FOREGROUND) &&
            newWindowHandle->getInfo()->inputConfig.test(
                    gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
    const sp<WindowInfoHandle> oldWallpaper =
            oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
    const sp<WindowInfoHandle> newWallpaper =
            newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr;
    if (oldWallpaper == newWallpaper) {
        return;
    }

    if (oldWallpaper != nullptr) {
        state.addOrUpdateWindow(oldWallpaper, InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
                                BitSet32(0));
    }

    if (newWallpaper != nullptr) {
        state.addOrUpdateWindow(newWallpaper,
                                InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER |
                                        InputTarget::FLAG_WINDOW_IS_OBSCURED |
                                        InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED,
                                pointerIds);
    }
}

void InputDispatcher::transferWallpaperTouch(int32_t oldTargetFlags, int32_t newTargetFlags,
                                             const sp<WindowInfoHandle> fromWindowHandle,
                                             const sp<WindowInfoHandle> toWindowHandle,
                                             TouchState& state, const BitSet32& pointerIds) {
    const bool oldHasWallpaper = (oldTargetFlags & InputTarget::FLAG_FOREGROUND) &&
            fromWindowHandle->getInfo()->inputConfig.test(
                    gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
    const bool newHasWallpaper = (newTargetFlags & InputTarget::FLAG_FOREGROUND) &&
            toWindowHandle->getInfo()->inputConfig.test(
                    gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);

    const sp<WindowInfoHandle> oldWallpaper =
            oldHasWallpaper ? state.getWallpaperWindow() : nullptr;
    const sp<WindowInfoHandle> newWallpaper =
            newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr;
    if (oldWallpaper == newWallpaper) {
        return;
    }

    if (oldWallpaper != nullptr) {
        CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
                                   "transferring touch focus to another window");
        state.removeWindowByToken(oldWallpaper->getToken());
        synthesizeCancelationEventsForWindowLocked(oldWallpaper, options);
    }

    if (newWallpaper != nullptr) {
        int32_t wallpaperFlags =
                oldTargetFlags & (InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
        wallpaperFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED |
                InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
        state.addOrUpdateWindow(newWallpaper, wallpaperFlags, pointerIds);
        sp<Connection> wallpaperConnection = getConnectionLocked(newWallpaper->getToken());
        if (wallpaperConnection != nullptr) {
            sp<Connection> toConnection = getConnectionLocked(toWindowHandle->getToken());
            toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
            synthesizePointerDownEventsForConnectionLocked(wallpaperConnection, wallpaperFlags);
        }
    }
}

sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
        const sp<WindowInfoHandle>& windowHandle) const {
    const std::vector<sp<WindowInfoHandle>>& windowHandles =
            getWindowHandlesLocked(windowHandle->getInfo()->displayId);
    bool foundWindow = false;
    for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
        if (!foundWindow && otherHandle != windowHandle) {
            continue;
        }
        if (windowHandle == otherHandle) {
            foundWindow = true;
            continue;
        }

        if (otherHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::IS_WALLPAPER)) {
            return otherHandle;
        }
    }
    return nullptr;
}

} // namespace android::inputdispatcher
+18 −2
Original line number Diff line number Diff line
@@ -621,8 +621,12 @@ private:
                                                        const CancelationOptions& options)
            REQUIRES(mLock);

    void synthesizePointerDownEventsForConnectionLocked(const sp<Connection>& connection)
            REQUIRES(mLock);
    void synthesizePointerDownEventsForConnectionLocked(const sp<Connection>& connection,
                                                        int32_t targetFlags) REQUIRES(mLock);

    void synthesizeCancelationEventsForWindowLocked(
            const sp<android::gui::WindowInfoHandle>& windowHandle,
            const CancelationOptions& options) REQUIRES(mLock);

    // Splitting motion events across windows.
    std::unique_ptr<MotionEntry> splitMotionEvent(const MotionEntry& originalMotionEntry,
@@ -684,6 +688,18 @@ private:
    bool recentWindowsAreOwnedByLocked(int32_t pid, int32_t uid) REQUIRES(mLock);

    sp<InputReporterInterface> mReporter;

    void slipWallpaperTouch(int32_t targetFlags,
                            const sp<android::gui::WindowInfoHandle>& oldWindowHandle,
                            const sp<android::gui::WindowInfoHandle>& newWindowHandle,
                            TouchState& state, const BitSet32& pointerIds) REQUIRES(mLock);
    void transferWallpaperTouch(int32_t oldTargetFlags, int32_t newTargetFlags,
                                const sp<android::gui::WindowInfoHandle> fromWindowHandle,
                                const sp<android::gui::WindowInfoHandle> toWindowHandle,
                                TouchState& state, const BitSet32& pointerIds) REQUIRES(mLock);

    sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow(
            const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock);
};

} // namespace android::inputdispatcher
+140 −61

File changed.

Preview size limit exceeded, changes collapsed.

Loading