diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h index 78a36089e..8a7545dda 100644 --- a/include/gui/ConsumerBase.h +++ b/include/gui/ConsumerBase.h @@ -89,6 +89,18 @@ protected: // buffers from the given BufferQueue. ConsumerBase(const sp &bufferQueue); + // onLastStrongRef gets called by RefBase just before the dtor of the most + // derived class. It is used to clean up the buffers so that ConsumerBase + // can coordinate the clean-up by calling into virtual methods implemented + // by the derived classes. This would not be possible from the + // ConsuemrBase dtor because by the time that gets called the derived + // classes have already been destructed. + // + // This methods should not need to be overridden by derived classes, but + // if they are overridden the ConsumerBase implementation must be called + // from the derived class. + virtual void onLastStrongRef(const void* id); + // Implementation of the BufferQueue::ConsumerListener interface. These // calls are used to notify the ConsumerBase of asynchronous events in the // BufferQueue. These methods should not need to be overridden by derived diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index 8694d21c8..4937b1734 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -76,7 +76,18 @@ ConsumerBase::ConsumerBase(const sp& bufferQueue) : } ConsumerBase::~ConsumerBase() { - CB_LOGV("~ConsumerBase"); + CB_LOGV("~ConsumerBase"); + Mutex::Autolock lock(mMutex); + + // Verify that abandon() has been called before we get here. This should + // be done by ConsumerBase::onLastStrongRef(), but it's possible for a + // derived class to override that method and not call + // ConsumerBase::onLastStrongRef(). + LOG_ALWAYS_FATAL_IF(!mAbandoned, "[%s] ~ConsumerBase was called, but the " + "consumer is not abandoned!", mName.string()); +} + +void ConsumerBase::onLastStrongRef(const void* id) { abandon(); } diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index ce960367b..7376b4ce8 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -178,21 +178,21 @@ TEST_F(SurfaceTextureClientTest, EglSwapBuffersAbandonErrorIsEglBadSurface) { EXPECT_EQ(EGL_SUCCESS, eglGetError()); EGLBoolean success = eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext); - EXPECT_EQ(EGL_TRUE, success); + EXPECT_TRUE(success); glClear(GL_COLOR_BUFFER_BIT); success = eglSwapBuffers(mEglDisplay, eglSurface); - EXPECT_EQ(EGL_TRUE, success); + EXPECT_TRUE(success); mST->abandon(); glClear(GL_COLOR_BUFFER_BIT); success = eglSwapBuffers(mEglDisplay, eglSurface); - EXPECT_EQ(EGL_FALSE, success); + EXPECT_FALSE(success); EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); success = eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - ASSERT_EQ(EGL_TRUE, success); + ASSERT_TRUE(success); if (eglSurface != EGL_NO_SURFACE) { eglDestroySurface(mEglDisplay, eglSurface);