Surface: Add a death notification to SurfaceListener
As we move away from IGBPs being available generally, clients may still
want to know if the other end of the Surface dies on them.
With no binder object available to them, if the client requests it, we
wrap the callback in a proxy and notify via
SurfaceListener::onRemoteDied when they request it via
SurfaceListener::needsDeathNotify.
See go/warren-buffers for more details.
BYPASS_IGBP_IGBC_API_REASON=warren buffers
Bug: 340933794
Flag: com.android.graphics.libgui.flags.wb_platform_api_improvements
Test: new tests in libgui_test
Change-Id: I102c21436ba3d852481bfa636c5de102ef244e4a
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index da3886c..76d74fe 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -77,9 +77,28 @@
} // namespace
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+Surface::ProducerDeathListenerProxy::ProducerDeathListenerProxy(wp<SurfaceListener> surfaceListener)
+ : mSurfaceListener(surfaceListener) {}
+
+void Surface::ProducerDeathListenerProxy::binderDied(const wp<IBinder>&) {
+ sp<SurfaceListener> surfaceListener = mSurfaceListener.promote();
+ if (!surfaceListener) {
+ return;
+ }
+
+ if (surfaceListener->needsDeathNotify()) {
+ surfaceListener->onRemoteDied();
+ }
+}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,
const sp<IBinder>& surfaceControlHandle)
: mGraphicBufferProducer(bufferProducer),
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ mSurfaceDeathListener(nullptr),
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
mCrop(Rect::EMPTY_RECT),
mBufferAge(0),
mGenerationNumber(0),
@@ -134,6 +153,12 @@
if (mConnectedToCpu) {
Surface::disconnect(NATIVE_WINDOW_API_CPU);
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ if (mSurfaceDeathListener != nullptr) {
+ IInterface::asBinder(mGraphicBufferProducer)->unlinkToDeath(mSurfaceDeathListener);
+ mSurfaceDeathListener = nullptr;
+ }
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
}
sp<ISurfaceComposer> Surface::composerService() const {
@@ -2033,6 +2058,7 @@
Mutex::Autolock lock(mMutex);
IGraphicBufferProducer::QueueBufferOutput output;
mReportRemovedBuffers = reportBufferRemoval;
+
if (listener != nullptr) {
mListenerProxy = new ProducerListenerProxy(this, listener);
}
@@ -2053,6 +2079,13 @@
}
mConsumerRunningBehind = (output.numPendingBuffers >= 2);
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ if (listener && listener->needsDeathNotify()) {
+ mSurfaceDeathListener = sp<ProducerDeathListenerProxy>::make(listener);
+ IInterface::asBinder(mGraphicBufferProducer)->linkToDeath(mSurfaceDeathListener);
+ }
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
}
if (!err && api == NATIVE_WINDOW_API_CPU) {
mConnectedToCpu = true;
@@ -2093,6 +2126,14 @@
mConnectedToCpu = false;
}
}
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ if (mSurfaceDeathListener != nullptr) {
+ IInterface::asBinder(mGraphicBufferProducer)->unlinkToDeath(mSurfaceDeathListener);
+ mSurfaceDeathListener = nullptr;
+ }
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
return err;
}