Loading services/surfaceflinger/SurfaceFlinger.cpp +2 −5 Original line number Diff line number Diff line Loading @@ -3722,11 +3722,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. Loading services/surfaceflinger/WindowInfosListenerInvoker.cpp +39 −69 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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) { Loading @@ -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); Loading @@ -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 services/surfaceflinger/WindowInfosListenerInvoker.h +9 −15 Original line number Diff line number Diff line Loading @@ -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 Loading
services/surfaceflinger/SurfaceFlinger.cpp +2 −5 Original line number Diff line number Diff line Loading @@ -3722,11 +3722,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. Loading
services/surfaceflinger/WindowInfosListenerInvoker.cpp +39 −69 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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) { Loading @@ -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); Loading @@ -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
services/surfaceflinger/WindowInfosListenerInvoker.h +9 −15 Original line number Diff line number Diff line Loading @@ -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