Added IWindowInfosChangedListener interface
Added WindowInfosChangedListener interface and the ability to
register a WindowInfosChangedListener in SCC. Also added the
SurfaceFlinger code where the WindowInfosChangedListener gets
registered and reports to the listeners.
Test: Existing tests pass
Bug: 188792659
Change-Id: If7b93df0afd71a88ea703d2113e68bfb549368af
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 34b8281..eeb3f3a 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -158,6 +158,7 @@
"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 7f5569b..39f7e32 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 android::hardware::power::Boost;
using base::StringAppendF;
+using gui::IWindowInfosListener;
using gui::WindowInfo;
using ui::ColorMode;
using ui::Dataspace;
@@ -355,7 +357,8 @@
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 @@
}
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 @@
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 a88de87..5a1b445 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -102,6 +102,7 @@
class RenderArea;
class TimeStats;
class FrameTracer;
+class WindowInfosListenerInvoker;
using gui::ScreenCaptureResults;
@@ -717,6 +718,11 @@
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 @@
}
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 0000000..55136fb
--- /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 0000000..b979de1
--- /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