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

Commit 466727a0 authored by Patrick Williams's avatar Patrick Williams Committed by Automerger Merge Worker
Browse files

Merge "Revert "SF: throttle WindowInfosListener calls"" into udc-dev am: ee76c8ca am: b62025c8

parents 9cba62a0 b62025c8
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -3707,11 +3707,8 @@ void SurfaceFlinger::updateInputFlinger() {
        ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
        if (updateWindowInfo) {
            mWindowInfosListenerInvoker
                    ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos),
                                         std::move(
                                                 inputWindowCommands.windowInfosReportedListeners),
                                         /* forceImmediateCall= */
                                         !inputWindowCommands.focusRequests.empty());
                    ->windowInfosChanged(windowInfos, displayInfos,
                                         inputWindowCommands.windowInfosReportedListeners);
        } else {
            // If there are listeners but no changes to input windows, call the listeners
            // immediately.
+39 −69
Original line number Diff line number Diff line
@@ -25,14 +25,20 @@ using gui::DisplayInfo;
using gui::IWindowInfosListener;
using gui::WindowInfo;

struct WindowInfosReportedListenerInvoker : gui::BnWindowInfosReportedListener,
                                            IBinder::DeathRecipient {
    WindowInfosReportedListenerInvoker(size_t callbackCount,
                                       WindowInfosReportedListenerSet windowInfosReportedListeners)
struct WindowInfosListenerInvoker::WindowInfosReportedListener : gui::BnWindowInfosReportedListener,
                                                                 DeathRecipient {
    explicit WindowInfosReportedListener(
            size_t callbackCount,
            const std::unordered_set<sp<gui::IWindowInfosReportedListener>,
                                     SpHash<gui::IWindowInfosReportedListener>>&
                    windowInfosReportedListeners)
          : mCallbacksPending(callbackCount),
            mWindowInfosReportedListeners(std::move(windowInfosReportedListeners)) {}
            mWindowInfosReportedListeners(windowInfosReportedListeners) {}

    binder::Status onWindowInfosReported() override {
        // TODO(b/222421815) There could potentially be callbacks that we don't need to wait for
        // before calling the WindowInfosReportedListeners coming from InputWindowCommands. Filter
        // the list of callbacks down to those from system server.
        if (--mCallbacksPending == 0) {
            for (const auto& listener : mWindowInfosReportedListeners) {
                sp<IBinder> asBinder = IInterface::asBinder(listener);
@@ -48,7 +54,9 @@ struct WindowInfosReportedListenerInvoker : gui::BnWindowInfosReportedListener,

private:
    std::atomic<size_t> mCallbacksPending;
    WindowInfosReportedListenerSet mWindowInfosReportedListeners;
    std::unordered_set<sp<gui::IWindowInfosReportedListener>,
                       SpHash<gui::IWindowInfosReportedListener>>
            mWindowInfosReportedListeners;
};

void WindowInfosListenerInvoker::addWindowInfosListener(sp<IWindowInfosListener> listener) {
@@ -74,12 +82,10 @@ void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) {
}

void WindowInfosListenerInvoker::windowInfosChanged(
        std::vector<WindowInfo> windowInfos, std::vector<DisplayInfo> displayInfos,
        WindowInfosReportedListenerSet reportedListeners, bool forceImmediateCall) {
    reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this));
    auto callListeners = [this, windowInfos = std::move(windowInfos),
                          displayInfos = std::move(displayInfos),
                          reportedListeners = std::move(reportedListeners)]() mutable {
        const std::vector<WindowInfo>& windowInfos, const std::vector<DisplayInfo>& displayInfos,
        const std::unordered_set<sp<gui::IWindowInfosReportedListener>,
                                 SpHash<gui::IWindowInfosReportedListener>>&
                windowInfosReportedListeners) {
    ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
    {
        std::scoped_lock lock(mListenersMutex);
@@ -88,62 +94,26 @@ void WindowInfosListenerInvoker::windowInfosChanged(
        }
    }

        auto reportedInvoker =
                sp<WindowInfosReportedListenerInvoker>::make(windowInfosListeners.size(),
                                                             std::move(reportedListeners));

    auto windowInfosReportedListener = windowInfosReportedListeners.empty()
            ? nullptr
            : sp<WindowInfosReportedListener>::make(windowInfosListeners.size(),
                                                    windowInfosReportedListeners);
    for (const auto& listener : windowInfosListeners) {
        sp<IBinder> asBinder = IInterface::asBinder(listener);

        // linkToDeath is used here to ensure that the windowInfosReportedListeners
        // are called even if one of the windowInfosListeners dies before
        // calling onWindowInfosReported.
            asBinder->linkToDeath(reportedInvoker);

            auto status =
                    listener->onWindowInfosChanged(windowInfos, displayInfos, reportedInvoker);
            if (!status.isOk()) {
                reportedInvoker->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);
            return;
        }

        mWindowInfosChangedDelayed = nullptr;
        mActiveMessageCount++;
    }
    callListeners();
        if (windowInfosReportedListener) {
            asBinder->linkToDeath(windowInfosReportedListener);
        }

binder::Status WindowInfosListenerInvoker::onWindowInfosReported() {
    std::function<void()> callListeners;

    {
        std::scoped_lock lock{mMessagesMutex};
        mActiveMessageCount--;
        if (!mWindowInfosChangedDelayed || mActiveMessageCount > 0) {
            return binder::Status::ok();
        auto status = listener->onWindowInfosChanged(windowInfos, displayInfos,
                                                     windowInfosReportedListener);
        if (windowInfosReportedListener && !status.isOk()) {
            windowInfosReportedListener->onWindowInfosReported();
        }

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

    callListeners();
    return binder::Status::ok();
}

} // namespace android
+9 −15
Original line number Diff line number Diff line
@@ -23,40 +23,34 @@
#include <android/gui/IWindowInfosReportedListener.h>
#include <binder/IBinder.h>
#include <ftl/small_map.h>
#include <gui/SpHash.h>
#include <utils/Mutex.h>

namespace android {

using WindowInfosReportedListenerSet =
        std::unordered_set<sp<gui::IWindowInfosReportedListener>,
                           gui::SpHash<gui::IWindowInfosReportedListener>>;
class SurfaceFlinger;

class WindowInfosListenerInvoker : public gui::BnWindowInfosReportedListener,
                                   public IBinder::DeathRecipient {
class WindowInfosListenerInvoker : public IBinder::DeathRecipient {
public:
    void addWindowInfosListener(sp<gui::IWindowInfosListener>);
    void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener);

    void windowInfosChanged(std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>,
                            WindowInfosReportedListenerSet windowInfosReportedListeners,
                            bool forceImmediateCall);

    binder::Status onWindowInfosReported() override;
    void windowInfosChanged(const std::vector<gui::WindowInfo>&,
                            const std::vector<gui::DisplayInfo>&,
                            const std::unordered_set<sp<gui::IWindowInfosReportedListener>,
                                                     SpHash<gui::IWindowInfosReportedListener>>&
                                    windowInfosReportedListeners);

protected:
    void binderDied(const wp<IBinder>& who) override;

private:
    struct WindowInfosReportedListener;

    std::mutex mListenersMutex;

    static constexpr size_t kStaticCapacity = 3;
    ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity>
            mWindowInfosListeners GUARDED_BY(mListenersMutex);

    std::mutex mMessagesMutex;
    uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0;
    std::function<void()> mWindowInfosChangedDelayed GUARDED_BY(mMessagesMutex);
};

} // namespace android