diff options
-rw-r--r-- | libs/gui/Android.bp | 2 | ||||
-rw-r--r-- | libs/gui/BufferQueueCore.cpp | 1 | ||||
-rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 31 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 24 | ||||
-rw-r--r-- | libs/gui/WindowInfosListenerReporter.cpp | 92 | ||||
-rw-r--r-- | libs/gui/android/gui/IWindowInfosListener.aidl | 25 | ||||
-rw-r--r-- | libs/gui/include/gui/ISurfaceComposer.h | 8 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 4 | ||||
-rw-r--r-- | libs/gui/include/gui/WindowInfosListener.h | 28 | ||||
-rw-r--r-- | libs/gui/include/gui/WindowInfosListenerReporter.h | 47 | ||||
-rw-r--r-- | libs/gui/tests/Surface_test.cpp | 10 | ||||
-rw-r--r-- | services/surfaceflinger/Android.bp | 1 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 25 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 8 | ||||
-rw-r--r-- | services/surfaceflinger/WindowInfosListenerInvoker.cpp | 65 | ||||
-rw-r--r-- | services/surfaceflinger/WindowInfosListenerInvoker.h | 47 |
16 files changed, 409 insertions, 9 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 2d8fff91da..4f57d576a4 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -67,6 +67,7 @@ cc_library_static { ":guiconstants_aidl", "android/gui/FocusRequest.aidl", "android/gui/InputApplicationInfo.aidl", + "android/gui/IWindowInfosListener.aidl", "android/gui/WindowInfo.aidl", "WindowInfo.cpp", ], @@ -189,6 +190,7 @@ cc_library_shared { "SyncFeatures.cpp", "TransactionTracing.cpp", "view/Surface.cpp", + "WindowInfosListenerReporter.cpp", "bufferqueue/1.0/B2HProducerListener.cpp", "bufferqueue/1.0/H2BGraphicBufferProducer.cpp", "bufferqueue/2.0/B2HProducerListener.cpp", diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp index 5023b6bb81..2930154ad4 100644 --- a/libs/gui/BufferQueueCore.cpp +++ b/libs/gui/BufferQueueCore.cpp @@ -34,7 +34,6 @@ #include <gui/BufferQueueCore.h> #include <gui/IConsumerListener.h> #include <gui/IProducerListener.h> -#include <gui/ISurfaceComposer.h> #include <private/gui/ComposerService.h> #include <system/window.h> diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 0d7795e1ba..2a980bd118 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -44,6 +44,7 @@ namespace android { +using gui::IWindowInfosListener; using ui::ColorMode; class BpSurfaceComposer : public BpInterface<ISurfaceComposer> @@ -1227,6 +1228,22 @@ public: return reply.readInt32(buffers); } + + status_t addWindowInfosListener( + const sp<IWindowInfosListener>& windowInfosListener) const override { + Parcel data, reply; + SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor()); + SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(windowInfosListener)); + return remote()->transact(BnSurfaceComposer::ADD_WINDOW_INFOS_LISTENER, data, &reply); + } + + status_t removeWindowInfosListener( + const sp<IWindowInfosListener>& windowInfosListener) const override { + Parcel data, reply; + SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor()); + SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(windowInfosListener)); + return remote()->transact(BnSurfaceComposer::REMOVE_WINDOW_INFOS_LISTENER, data, &reply); + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -2107,6 +2124,20 @@ status_t BnSurfaceComposer::onTransact( SAFE_PARCEL(reply->writeBool, success); return err; } + case ADD_WINDOW_INFOS_LISTENER: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp<IWindowInfosListener> listener; + SAFE_PARCEL(data.readStrongBinder, &listener); + + return addWindowInfosListener(listener); + } + case REMOVE_WINDOW_INFOS_LISTENER: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp<IWindowInfosListener> listener; + SAFE_PARCEL(data.readStrongBinder, &listener); + + return removeWindowInfosListener(listener); + } default: { return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index c52c644eb7..8547739420 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> +#include <android/gui/IWindowInfosListener.h> #include <utils/Errors.h> #include <utils/Log.h> #include <utils/SortedVector.h> @@ -54,6 +55,7 @@ namespace android { using gui::FocusRequest; using gui::WindowInfo; using gui::WindowInfoHandle; +using gui::WindowInfosListener; using ui::ColorMode; // --------------------------------------------------------------------------- @@ -95,6 +97,7 @@ bool ComposerService::connectLocked() { if (instance.mComposerService == nullptr) { if (ComposerService::getInstance().connectLocked()) { ALOGD("ComposerService reconnected"); + WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService); } } return instance.mComposerService; @@ -1768,15 +1771,10 @@ void SurfaceComposerClient::Transaction::setDisplaySize(const sp<IBinder>& token // --------------------------------------------------------------------------- -SurfaceComposerClient::SurfaceComposerClient() - : mStatus(NO_INIT) -{ -} +SurfaceComposerClient::SurfaceComposerClient() : mStatus(NO_INIT) {} SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client) - : mStatus(NO_ERROR), mClient(client) -{ -} + : mStatus(NO_ERROR), mClient(client) {} void SurfaceComposerClient::onFirstRef() { sp<ISurfaceComposer> sf(ComposerService::getComposerService()); @@ -2142,6 +2140,18 @@ int SurfaceComposerClient::getGPUContextPriority() { return ComposerService::getComposerService()->getGPUContextPriority(); } +status_t SurfaceComposerClient::addWindowInfosListener( + const sp<WindowInfosListener>& windowInfosListener) { + return WindowInfosListenerReporter::getInstance() + ->addWindowInfosListener(windowInfosListener, ComposerService::getComposerService()); +} + +status_t SurfaceComposerClient::removeWindowInfosListener( + const sp<WindowInfosListener>& windowInfosListener) { + return WindowInfosListenerReporter::getInstance() + ->removeWindowInfosListener(windowInfosListener, ComposerService::getComposerService()); +} + // ---------------------------------------------------------------------------- status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs, diff --git a/libs/gui/WindowInfosListenerReporter.cpp b/libs/gui/WindowInfosListenerReporter.cpp new file mode 100644 index 0000000000..834e2b8433 --- /dev/null +++ b/libs/gui/WindowInfosListenerReporter.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gui/ISurfaceComposer.h> +#include <gui/WindowInfosListenerReporter.h> + +namespace android { + +using gui::WindowInfo; +using gui::WindowInfosListener; + +sp<WindowInfosListenerReporter> WindowInfosListenerReporter::getInstance() { + static sp<WindowInfosListenerReporter> sInstance = new WindowInfosListenerReporter; + return sInstance; +} + +status_t WindowInfosListenerReporter::addWindowInfosListener( + const sp<WindowInfosListener>& windowInfosListener, + const sp<ISurfaceComposer>& surfaceComposer) { + status_t status = OK; + { + std::scoped_lock lock(mListenersMutex); + if (mWindowInfosListeners.empty()) { + status = surfaceComposer->addWindowInfosListener(this); + } + + if (status == OK) { + mWindowInfosListeners.insert(windowInfosListener); + } + } + + return status; +} + +status_t WindowInfosListenerReporter::removeWindowInfosListener( + const sp<WindowInfosListener>& windowInfosListener, + const sp<ISurfaceComposer>& surfaceComposer) { + status_t status = OK; + { + std::scoped_lock lock(mListenersMutex); + if (mWindowInfosListeners.size() == 1) { + status = surfaceComposer->removeWindowInfosListener(this); + } + + if (status == OK) { + mWindowInfosListeners.erase(windowInfosListener); + } + } + + return status; +} + +binder::Status WindowInfosListenerReporter::onWindowInfosChanged( + const std::vector<WindowInfo>& windowInfos) { + std::unordered_set<sp<WindowInfosListener>, ISurfaceComposer::SpHash<WindowInfosListener>> + windowInfosListeners; + + { + std::scoped_lock lock(mListenersMutex); + for (auto listener : mWindowInfosListeners) { + windowInfosListeners.insert(listener); + } + } + + for (auto listener : windowInfosListeners) { + listener->onWindowInfosChanged(windowInfos); + } + + return binder::Status::ok(); +} + +void WindowInfosListenerReporter::reconnect(const sp<ISurfaceComposer>& composerService) { + std::scoped_lock lock(mListenersMutex); + if (!mWindowInfosListeners.empty()) { + composerService->addWindowInfosListener(this); + } +} + +} // namespace android
\ No newline at end of file diff --git a/libs/gui/android/gui/IWindowInfosListener.aidl b/libs/gui/android/gui/IWindowInfosListener.aidl new file mode 100644 index 0000000000..500d928a5a --- /dev/null +++ b/libs/gui/android/gui/IWindowInfosListener.aidl @@ -0,0 +1,25 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.gui; + +import android.gui.WindowInfo; + +/** @hide */ +oneway interface IWindowInfosListener +{ + void onWindowInfosChanged(in WindowInfo[] windowInfos); +} diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 71b80d3929..ad7bcb7d12 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -22,6 +22,7 @@ #include <android/gui/IScreenCaptureListener.h> #include <android/gui/ITransactionTraceListener.h> #include <android/gui/ITunnelModeEnabledListener.h> +#include <android/gui/IWindowInfosListener.h> #include <binder/IBinder.h> #include <binder/IInterface.h> #include <ftl/Flags.h> @@ -552,6 +553,11 @@ public: * in MIN_UNDEQUEUED_BUFFERS. */ virtual status_t getMaxAcquiredBufferCount(int* buffers) const = 0; + + virtual status_t addWindowInfosListener( + const sp<gui::IWindowInfosListener>& windowInfosListener) const = 0; + virtual status_t removeWindowInfosListener( + const sp<gui::IWindowInfosListener>& windowInfosListener) const = 0; }; // ---------------------------------------------------------------------------- @@ -624,6 +630,8 @@ public: ON_PULL_ATOM, ADD_TUNNEL_MODE_ENABLED_LISTENER, REMOVE_TUNNEL_MODE_ENABLED_LISTENER, + ADD_WINDOW_INFOS_LISTENER, + REMOVE_WINDOW_INFOS_LISTENER, // Always append new enum to the end. }; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index ff97fe4ce6..e718f3d478 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -42,6 +42,7 @@ #include <gui/ITransactionCompletedListener.h> #include <gui/LayerState.h> #include <gui/SurfaceControl.h> +#include <gui/WindowInfosListenerReporter.h> #include <math/vec3.h> namespace android { @@ -619,6 +620,9 @@ public: static status_t removeTunnelModeEnabledListener( const sp<gui::ITunnelModeEnabledListener>& listener); + status_t addWindowInfosListener(const sp<gui::WindowInfosListener>& windowInfosListener); + status_t removeWindowInfosListener(const sp<gui::WindowInfosListener>& windowInfosListener); + private: virtual void onFirstRef(); diff --git a/libs/gui/include/gui/WindowInfosListener.h b/libs/gui/include/gui/WindowInfosListener.h new file mode 100644 index 0000000000..8a70b9bb57 --- /dev/null +++ b/libs/gui/include/gui/WindowInfosListener.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <gui/WindowInfo.h> +#include <utils/RefBase.h> + +namespace android::gui { + +class WindowInfosListener : public virtual RefBase { +public: + virtual void onWindowInfosChanged(const std::vector<WindowInfo>& /*windowInfos*/) = 0; +}; +} // namespace android::gui
\ No newline at end of file diff --git a/libs/gui/include/gui/WindowInfosListenerReporter.h b/libs/gui/include/gui/WindowInfosListenerReporter.h new file mode 100644 index 0000000000..3e346de069 --- /dev/null +++ b/libs/gui/include/gui/WindowInfosListenerReporter.h @@ -0,0 +1,47 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <android/gui/BnWindowInfosListener.h> +#include <binder/IBinder.h> +#include <gui/ISurfaceComposer.h> +#include <gui/WindowInfosListener.h> +#include <utils/Mutex.h> +#include <unordered_set> + +namespace android { +class ISurfaceComposer; + +class WindowInfosListenerReporter : public gui::BnWindowInfosListener { +public: + static sp<WindowInfosListenerReporter> getInstance(); + + binder::Status onWindowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos) override; + + status_t addWindowInfosListener(const sp<gui::WindowInfosListener>& windowInfosListener, + const sp<ISurfaceComposer>&); + status_t removeWindowInfosListener(const sp<gui::WindowInfosListener>& windowInfosListener, + const sp<ISurfaceComposer>&); + void reconnect(const sp<ISurfaceComposer>&); + +private: + std::mutex mListenersMutex; + std::unordered_set<sp<gui::WindowInfosListener>, + ISurfaceComposer::SpHash<gui::WindowInfosListener>> + mWindowInfosListeners GUARDED_BY(mListenersMutex); +}; +} // namespace android
\ No newline at end of file diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 59b0c04bc3..a02970c9bc 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -904,6 +904,16 @@ public: status_t getMaxAcquiredBufferCount(int* /*buffers*/) const override { return NO_ERROR; } + status_t addWindowInfosListener( + const sp<gui::IWindowInfosListener>& /*windowInfosListener*/) const override { + return NO_ERROR; + } + + status_t removeWindowInfosListener( + const sp<gui::IWindowInfosListener>& /*windowInfosListener*/) const override { + return NO_ERROR; + } + protected: IBinder* onAsBinder() override { return nullptr; } diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 34b8281153..eeb3f3a288 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -158,6 +158,7 @@ filegroup { "FrameTracer/FrameTracer.cpp", "FrameTracker.cpp", "HdrLayerInfoReporter.cpp", + "WindowInfosListenerInvoker.cpp", "Layer.cpp", "LayerProtoHelper.cpp", "LayerRejecter.cpp", diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 7f5569bd64..39f7e3290a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -133,6 +133,7 @@ #include "SurfaceInterceptor.h" #include "TimeStats/TimeStats.h" #include "TunnelModeEnabledReporter.h" +#include "WindowInfosListenerInvoker.h" #include "android-base/parseint.h" #include "android-base/stringprintf.h" #include "android-base/strings.h" @@ -167,6 +168,7 @@ using namespace android::sysprop; using android::hardware::power::Boost; using base::StringAppendF; +using gui::IWindowInfosListener; using gui::WindowInfo; using ui::ColorMode; using ui::Dataspace; @@ -355,7 +357,8 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()), mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)), - mPowerAdvisor(*this) { + mPowerAdvisor(*this), + mWindowInfosListenerInvoker(new WindowInfosListenerInvoker()) { ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); mSetInputWindowsListener = new SetInputWindowsListener([&]() { setInputWindowsFinished(); }); @@ -5336,6 +5339,14 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { } return PERMISSION_DENIED; } + case ADD_WINDOW_INFOS_LISTENER: + case REMOVE_WINDOW_INFOS_LISTENER: { + const int uid = IPCThreadState::self()->getCallingUid(); + if (uid == AID_SYSTEM || uid == AID_GRAPHICS) { + return OK; + } + return PERMISSION_DENIED; + } } // These codes are used for the IBinder protocol to either interrogate the recipient @@ -6990,6 +7001,18 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activ onActiveDisplaySizeChanged(activeDisplay); } +status_t SurfaceFlinger::addWindowInfosListener( + const sp<IWindowInfosListener>& windowInfosListener) const { + mWindowInfosListenerInvoker->addWindowInfosListener(windowInfosListener); + return NO_ERROR; +} + +status_t SurfaceFlinger::removeWindowInfosListener( + const sp<IWindowInfosListener>& windowInfosListener) const { + mWindowInfosListenerInvoker->removeWindowInfosListener(windowInfosListener); + return NO_ERROR; +} + } // namespace android #if defined(__gl_h_) diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a88de872df..5a1b445e74 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -102,6 +102,7 @@ class RegionSamplingThread; class RenderArea; class TimeStats; class FrameTracer; +class WindowInfosListenerInvoker; using gui::ScreenCaptureResults; @@ -717,6 +718,11 @@ private: status_t getMaxAcquiredBufferCount(int* buffers) const override; + status_t addWindowInfosListener( + const sp<gui::IWindowInfosListener>& windowInfosListener) const override; + status_t removeWindowInfosListener( + const sp<gui::IWindowInfosListener>& windowInfosListener) const override; + // Implements IBinder::DeathRecipient. void binderDied(const wp<IBinder>& who) override; @@ -1499,6 +1505,8 @@ private: } wp<IBinder> mActiveDisplayToken GUARDED_BY(mStateLock); + + const sp<WindowInfosListenerInvoker> mWindowInfosListenerInvoker; }; } // namespace android diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.cpp b/services/surfaceflinger/WindowInfosListenerInvoker.cpp new file mode 100644 index 0000000000..55136fb835 --- /dev/null +++ b/services/surfaceflinger/WindowInfosListenerInvoker.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "WindowInfosListenerInvoker.h" +#include <gui/ISurfaceComposer.h> +#include <unordered_set> + +namespace android { + +using gui::IWindowInfosListener; +using gui::WindowInfo; + +void WindowInfosListenerInvoker::addWindowInfosListener( + const sp<IWindowInfosListener>& windowInfosListener) { + sp<IBinder> asBinder = IInterface::asBinder(windowInfosListener); + + asBinder->linkToDeath(this); + std::scoped_lock lock(mListenersMutex); + mWindowInfosListeners.emplace(asBinder, windowInfosListener); +} + +void WindowInfosListenerInvoker::removeWindowInfosListener( + const sp<IWindowInfosListener>& windowInfosListener) { + sp<IBinder> asBinder = IInterface::asBinder(windowInfosListener); + + std::scoped_lock lock(mListenersMutex); + asBinder->unlinkToDeath(this); + mWindowInfosListeners.erase(asBinder); +} + +void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) { + std::scoped_lock lock(mListenersMutex); + mWindowInfosListeners.erase(who); +} + +void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos) { + std::unordered_set<sp<IWindowInfosListener>, ISurfaceComposer::SpHash<IWindowInfosListener>> + windowInfosListeners; + + { + std::scoped_lock lock(mListenersMutex); + for (const auto& [_, listener] : mWindowInfosListeners) { + windowInfosListeners.insert(listener); + } + } + + for (const auto& listener : windowInfosListeners) { + listener->onWindowInfosChanged(windowInfos); + } +} + +} // namespace android
\ No newline at end of file diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.h b/services/surfaceflinger/WindowInfosListenerInvoker.h new file mode 100644 index 0000000000..b979de1f70 --- /dev/null +++ b/services/surfaceflinger/WindowInfosListenerInvoker.h @@ -0,0 +1,47 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <android/gui/IWindowInfosListener.h> +#include <binder/IBinder.h> +#include <utils/Mutex.h> +#include <unordered_map> + +namespace android { + +class WindowInfosListenerInvoker : public IBinder::DeathRecipient { +public: + void addWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener); + void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener); + + void windowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos); + +protected: + void binderDied(const wp<IBinder>& who) override; + +private: + struct WpHash { + size_t operator()(const wp<IBinder>& p) const { + return std::hash<IBinder*>()(p.unsafe_get()); + } + }; + + std::mutex mListenersMutex; + std::unordered_map<wp<IBinder>, const sp<gui::IWindowInfosListener>, WpHash> + mWindowInfosListeners GUARDED_BY(mListenersMutex); +}; +} // namespace android
\ No newline at end of file |