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

Commit 15d58261 authored by Presubmit Automerger Backend's avatar Presubmit Automerger Backend
Browse files

[automerge] DO NOT MERGE Reverts WindowInfosListenerInvoker throttling 2p: fd9c44fb

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/22931281

Bug: 279649321
Bug: 270894765
Change-Id: Ie2899f2463b6125ea054f37e8066148f3436c56d
parents 28834126 fd9c44fb
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -2398,7 +2398,16 @@ WindowInfo Layer::fillInputInfo(const InputDisplayArgs& displayArgs) {
        info.inputConfig |= WindowInfo::InputConfig::NOT_TOUCHABLE;
    }

    info.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !isVisibleForInput());
    // For compatibility reasons we let layers which can receive input
    // receive input before they have actually submitted a buffer. Because
    // of this we use canReceiveInput instead of isVisible to check the
    // policy-visibility, ignoring the buffer state. However for layers with
    // hasInputInfo()==false we can use the real visibility state.
    // We are just using these layers for occlusion detection in
    // InputDispatcher, and obviously if they aren't visible they can't occlude
    // anything.
    const bool visible = hasInputInfo() ? canReceiveInput() : isVisible();
    info.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !visible);

    info.alpha = getAlpha();
    fillTouchOcclusionMode(info);
+0 −15
Original line number Diff line number Diff line
@@ -471,21 +471,6 @@ public:
     */
    virtual bool canReceiveInput() const;

    /*
     * Whether or not the layer should be considered visible for input calculations.
     */
    virtual bool isVisibleForInput() const {
        // For compatibility reasons we let layers which can receive input
        // receive input before they have actually submitted a buffer. Because
        // of this we use canReceiveInput instead of isVisible to check the
        // policy-visibility, ignoring the buffer state. However for layers with
        // hasInputInfo()==false we can use the real visibility state.
        // We are just using these layers for occlusion detection in
        // InputDispatcher, and obviously if they aren't visible they can't occlude
        // anything.
        return hasInputInfo() ? canReceiveInput() : isVisible();
    }

    /*
     * isProtected - true if the layer may contain protected contents in the
     * GRALLOC_USAGE_PROTECTED sense.
+3 −21
Original line number Diff line number Diff line
@@ -3269,34 +3269,16 @@ void SurfaceFlinger::updateInputFlinger() {
    if (!updateWindowInfo && mInputWindowCommands.empty()) {
        return;
    }

    std::unordered_set<Layer*> visibleLayers;
    mDrawingState.traverse([&visibleLayers](Layer* layer) {
        if (layer->isVisibleForInput()) {
            visibleLayers.insert(layer);
        }
    });
    bool visibleLayersChanged = false;
    if (visibleLayers != mVisibleLayers) {
        visibleLayersChanged = true;
        mVisibleLayers = std::move(visibleLayers);
    }

    BackgroundExecutor::getInstance().sendCallbacks({[updateWindowInfo,
                                                      windowInfos = std::move(windowInfos),
                                                      displayInfos = std::move(displayInfos),
                                                      inputWindowCommands =
                                                              std::move(mInputWindowCommands),
                                                      inputFlinger = mInputFlinger, this,
                                                      visibleLayersChanged]() {
                                                      inputFlinger = mInputFlinger, this]() {
        ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
        if (updateWindowInfo) {
            mWindowInfosListenerInvoker
                    ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos),
                                         /* shouldSync= */ inputWindowCommands.syncInputWindows,
                                         /* forceImmediateCall= */
                                         visibleLayersChanged ||
                                                 !inputWindowCommands.focusRequests.empty());
            mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos,
                                                            inputWindowCommands.syncInputWindows);
        } else if (inputWindowCommands.syncInputWindows) {
            // If the caller requested to sync input windows, but there are no
            // changes to input windows, notify immediately.
+0 −5
Original line number Diff line number Diff line
@@ -1454,11 +1454,6 @@ private:
    nsecs_t mAnimationTransactionTimeout = s2ns(5);

    friend class SurfaceComposerAIDL;

    // Layers visible during the last commit. This set should only be used for testing set equality
    // and membership. The pointers should not be dereferenced as it's possible the set contains
    // pointers to freed layers.
    std::unordered_set<Layer*> mVisibleLayers;
};

class SurfaceComposerAIDL : public gui::BnSurfaceComposer {
+20 −73
Original line number Diff line number Diff line
@@ -28,26 +28,19 @@ using gui::WindowInfo;

struct WindowInfosListenerInvoker::WindowInfosReportedListener
      : gui::BnWindowInfosReportedListener {
    explicit WindowInfosReportedListener(WindowInfosListenerInvoker& invoker, size_t callbackCount,
                                         bool shouldSync)
          : mInvoker(invoker), mCallbacksPending(callbackCount), mShouldSync(shouldSync) {}
    explicit WindowInfosReportedListener(WindowInfosListenerInvoker& invoker) : mInvoker(invoker) {}

    binder::Status onWindowInfosReported() override {
        mCallbacksPending--;
        if (mCallbacksPending == 0) {
            mInvoker.windowInfosReported(mShouldSync);
        }
        mInvoker.windowInfosReported();
        return binder::Status::ok();
    }

private:
    WindowInfosListenerInvoker& mInvoker;
    std::atomic<size_t> mCallbacksPending;
    bool mShouldSync;
};

WindowInfosListenerInvoker::WindowInfosListenerInvoker(SurfaceFlinger& flinger)
      : mFlinger(flinger) {}
      : mFlinger(flinger),
        mWindowInfosReportedListener(sp<WindowInfosReportedListener>::make(*this)) {}

void WindowInfosListenerInvoker::addWindowInfosListener(sp<IWindowInfosListener> listener) {
    sp<IBinder> asBinder = IInterface::asBinder(listener);
@@ -71,11 +64,9 @@ void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) {
    mWindowInfosListeners.erase(who);
}

void WindowInfosListenerInvoker::windowInfosChanged(std::vector<WindowInfo> windowInfos,
                                                    std::vector<DisplayInfo> displayInfos,
                                                    bool shouldSync, bool forceImmediateCall) {
    auto callListeners = [this, windowInfos = std::move(windowInfos),
                          displayInfos = std::move(displayInfos)](bool shouldSync) mutable {
void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos,
                                                    const std::vector<DisplayInfo>& displayInfos,
                                                    bool shouldSync) {
    ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
    {
        std::scoped_lock lock(mListenersMutex);
@@ -84,63 +75,19 @@ void WindowInfosListenerInvoker::windowInfosChanged(std::vector<WindowInfo> wind
        }
    }

        auto reportedListener =
                sp<WindowInfosReportedListener>::make(*this, windowInfosListeners.size(),
                                                      shouldSync);
    mCallbacksPending = windowInfosListeners.size();

    for (const auto& listener : windowInfosListeners) {
            auto status =
                    listener->onWindowInfosChanged(windowInfos, displayInfos, reportedListener);
            if (!status.isOk()) {
                reportedListener->onWindowInfosReported();
            }
        }
    };

    {
        std::scoped_lock lock(mMessagesMutex);
        // If there are unacked messages and this isn't a forced call, then return immediately.
        // If a forced window infos change doesn't happen first, the update will be sent after
        // the WindowInfosReportedListeners are called. If a forced window infos change happens or
        // if there are subsequent delayed messages before this update is sent, then this message
        // will be dropped and the listeners will only be called with the latest info. This is done
        // to reduce the amount of binder memory used.
        if (mActiveMessageCount > 0 && !forceImmediateCall) {
            mWindowInfosChangedDelayed = std::move(callListeners);
            mShouldSyncDelayed |= shouldSync;
            return;
        }

        mWindowInfosChangedDelayed = nullptr;
        shouldSync |= mShouldSyncDelayed;
        mShouldSyncDelayed = false;
        mActiveMessageCount++;
        listener->onWindowInfosChanged(windowInfos, displayInfos,
                                       shouldSync ? mWindowInfosReportedListener : nullptr);
    }
    callListeners(shouldSync);
}

void WindowInfosListenerInvoker::windowInfosReported(bool shouldSync) {
    if (shouldSync) {
void WindowInfosListenerInvoker::windowInfosReported() {
    mCallbacksPending--;
    if (mCallbacksPending == 0) {
        mFlinger.windowInfosReported();
    }

    std::function<void(bool)> callListeners;
    bool shouldSyncDelayed;
    {
        std::scoped_lock lock{mMessagesMutex};
        mActiveMessageCount--;
        if (!mWindowInfosChangedDelayed || mActiveMessageCount > 0) {
            return;
        }

        mActiveMessageCount++;
        callListeners = std::move(mWindowInfosChangedDelayed);
        mWindowInfosChangedDelayed = nullptr;
        shouldSyncDelayed = mShouldSyncDelayed;
        mShouldSyncDelayed = false;
    }

    callListeners(shouldSyncDelayed);
}

} // namespace android
Loading