Disconnect from surface when the RenderSurface object is removed.

When a display is created, SurfaceFlinger creates a DisplayDevice object that
handles connecting to the surface. This is done through the RenderSurface
class. However, there's no implicit call to disconnect the surface when the
DisplayDevice is removed, leaving the surface connected. This prevents the
surface from behing able to get connected to to another renderer.

This change adds the disconnect call in the destructor of the RenderSurface
object to ensure it's disconnected when the renderer is removed.

Fixes: 124415123
Test: No longer repro issue in bug
Test: VirtualDisplayTest.VirtualDisplayDestroyedSurfaceReuse
Test: libsurfaceflinger_unittest
Test: libcompositionengine_test
Change-Id: I2061e4e66c63f2b46608f599dcb31304ac8e11f5
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index e86d35d..6f076ad 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -68,6 +68,7 @@
         "mock/DisplaySurface.cpp",
         "mock/Layer.cpp",
         "mock/LayerFE.cpp",
+        "mock/NativeWindow.cpp",
         "mock/Output.cpp",
         "mock/OutputLayer.cpp",
         "mock/RenderSurface.cpp",
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/NativeWindow.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/NativeWindow.h
new file mode 100644
index 0000000..714d2f7
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/NativeWindow.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019 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 <gmock/gmock.h>
+#include <system/window.h>
+#include <ui/ANativeObjectBase.h>
+#include <ui/GraphicTypes.h>
+#include <ui/PixelFormat.h>
+
+namespace android::compositionengine::mock {
+
+/* ------------------------------------------------------------------------
+ * Mock NativeWindow
+ *
+ * An intentionally simplified Mock which implements a minimal subset of the full
+ * ANativeWindow interface.
+ */
+class NativeWindow : public ANativeObjectBase<ANativeWindow, NativeWindow, RefBase> {
+public:
+    NativeWindow();
+    ~NativeWindow();
+
+    MOCK_METHOD1(setSwapInterval, int(int));
+    MOCK_METHOD2(dequeueBuffer, int(struct ANativeWindowBuffer**, int*));
+    MOCK_METHOD2(cancelBuffer, int(struct ANativeWindowBuffer*, int));
+    MOCK_METHOD2(queueBuffer, int(struct ANativeWindowBuffer*, int));
+    MOCK_CONST_METHOD2(query, int(int, int*));
+    MOCK_METHOD1(connect, int(int));
+    MOCK_METHOD1(disconnect, int(int));
+    MOCK_METHOD1(lockBuffer_DEPRECATED, int(struct ANativeWindowBuffer*));
+    MOCK_METHOD1(setBuffersFormat, int(PixelFormat));
+    MOCK_METHOD1(setBuffersDataSpace, int(ui::Dataspace));
+    MOCK_METHOD1(setUsage, int(uint64_t));
+};
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/mock/NativeWindow.cpp b/services/surfaceflinger/CompositionEngine/mock/NativeWindow.cpp
new file mode 100644
index 0000000..d0cc8ef
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/mock/NativeWindow.cpp
@@ -0,0 +1,121 @@
+
+/*
+ * Copyright 2019 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 "compositionengine/mock/NativeWindow.h"
+#include <log/log.h>
+
+namespace android::compositionengine::mock {
+
+static int forwardSetSwapInterval(ANativeWindow* window, int interval) {
+    return static_cast<NativeWindow*>(window)->setSwapInterval(interval);
+}
+
+static int forwardDequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd) {
+    return static_cast<NativeWindow*>(window)->dequeueBuffer(buffer, fenceFd);
+}
+
+static int forwardCancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
+    return static_cast<NativeWindow*>(window)->cancelBuffer(buffer, fenceFd);
+}
+
+static int forwardQueueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
+    return static_cast<NativeWindow*>(window)->queueBuffer(buffer, fenceFd);
+}
+
+static int forwardQuery(const ANativeWindow* window, int what, int* value) {
+    return static_cast<const NativeWindow*>(window)->query(what, value);
+}
+
+static int forwardPerform(ANativeWindow* window, int operation, ...) {
+    va_list args;
+    va_start(args, operation);
+    int result = NO_ERROR;
+    switch (operation) {
+        case NATIVE_WINDOW_API_CONNECT: {
+            int api = va_arg(args, int);
+            result = static_cast<NativeWindow*>(window)->connect(api);
+            break;
+        }
+        case NATIVE_WINDOW_SET_BUFFERS_FORMAT: {
+            PixelFormat format = va_arg(args, PixelFormat);
+            result = static_cast<NativeWindow*>(window)->setBuffersFormat(format);
+            break;
+        }
+        case NATIVE_WINDOW_SET_BUFFERS_DATASPACE: {
+            ui::Dataspace dataspace = static_cast<ui::Dataspace>(va_arg(args, int));
+            result = static_cast<NativeWindow*>(window)->setBuffersDataSpace(dataspace);
+            break;
+        }
+        case NATIVE_WINDOW_SET_USAGE: {
+            // Note: Intentionally widens usage from 32 to 64 bits so we
+            // just have one implementation.
+            uint64_t usage = va_arg(args, uint32_t);
+            result = static_cast<NativeWindow*>(window)->setUsage(usage);
+            break;
+        }
+        case NATIVE_WINDOW_SET_USAGE64: {
+            uint64_t usage = va_arg(args, uint64_t);
+            result = static_cast<NativeWindow*>(window)->setUsage(usage);
+            break;
+        }
+        case NATIVE_WINDOW_API_DISCONNECT: {
+            int api = va_arg(args, int);
+            result = static_cast<NativeWindow*>(window)->disconnect(api);
+            break;
+        }
+        default:
+            LOG_ALWAYS_FATAL("Unexpected operation %d", operation);
+            break;
+    }
+
+    va_end(args);
+    return result;
+}
+
+static int forwardDequeueBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer** buffer) {
+    int ignoredFenceFd = -1;
+    return static_cast<NativeWindow*>(window)->dequeueBuffer(buffer, &ignoredFenceFd);
+}
+
+static int forwardCancelBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer* buffer) {
+    return static_cast<NativeWindow*>(window)->cancelBuffer(buffer, -1);
+}
+
+static int forwardLockBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer* buffer) {
+    return static_cast<NativeWindow*>(window)->lockBuffer_DEPRECATED(buffer);
+}
+
+static int forwardQueueBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer* buffer) {
+    return static_cast<NativeWindow*>(window)->queueBuffer(buffer, -1);
+}
+
+NativeWindow::NativeWindow() {
+    ANativeWindow::setSwapInterval = &forwardSetSwapInterval;
+    ANativeWindow::dequeueBuffer = &forwardDequeueBuffer;
+    ANativeWindow::cancelBuffer = &forwardCancelBuffer;
+    ANativeWindow::queueBuffer = &forwardQueueBuffer;
+    ANativeWindow::query = &forwardQuery;
+    ANativeWindow::perform = &forwardPerform;
+
+    ANativeWindow::dequeueBuffer_DEPRECATED = &forwardDequeueBufferDeprecated;
+    ANativeWindow::cancelBuffer_DEPRECATED = &forwardCancelBufferDeprecated;
+    ANativeWindow::lockBuffer_DEPRECATED = &forwardLockBufferDeprecated;
+    ANativeWindow::queueBuffer_DEPRECATED = &forwardQueueBufferDeprecated;
+}
+NativeWindow::~NativeWindow() = default;
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index b4dfba1..b5a6678 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -52,9 +52,14 @@
         mDisplay(display),
         mNativeWindow(args.nativeWindow),
         mDisplaySurface(args.displaySurface),
-        mSize(args.displayWidth, args.displayHeight) {}
+        mSize(args.displayWidth, args.displayHeight) {
+    LOG_ALWAYS_FATAL_IF(!mNativeWindow);
+}
 
-RenderSurface::~RenderSurface() = default;
+RenderSurface::~RenderSurface() {
+    ANativeWindow* const window = mNativeWindow.get();
+    native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
+}
 
 bool RenderSurface::isValid() const {
     return mSize.isValid();
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index cd2d454..33444a5 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -22,9 +22,9 @@
 #include <compositionengine/RenderSurfaceCreationArgs.h>
 #include <compositionengine/impl/Display.h>
 #include <compositionengine/mock/CompositionEngine.h>
+#include <compositionengine/mock/NativeWindow.h>
 #include <compositionengine/mock/RenderSurface.h>
 #include <gtest/gtest.h>
-#include <system/window.h>
 
 #include "MockHWComposer.h"
 
@@ -43,6 +43,7 @@
 
     StrictMock<android::mock::HWComposer> mHwComposer;
     StrictMock<mock::CompositionEngine> mCompositionEngine;
+    sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>();
     impl::Display mDisplay{mCompositionEngine,
                            DisplayCreationArgsBuilder().setDisplayId(DEFAULT_DISPLAY_ID).build()};
 };
@@ -199,8 +200,9 @@
  */
 
 TEST_F(DisplayTest, createRenderSurfaceSetsRenderSurface) {
+    EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL)).WillRepeatedly(Return(NO_ERROR));
     EXPECT_TRUE(mDisplay.getRenderSurface() == nullptr);
-    mDisplay.createRenderSurface(RenderSurfaceCreationArgs{640, 480, nullptr, nullptr});
+    mDisplay.createRenderSurface(RenderSurfaceCreationArgs{640, 480, mNativeWindow, nullptr});
     EXPECT_TRUE(mDisplay.getRenderSurface() != nullptr);
 }
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 84af9b9..9960478 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -22,11 +22,10 @@
 #include <compositionengine/mock/CompositionEngine.h>
 #include <compositionengine/mock/Display.h>
 #include <compositionengine/mock/DisplaySurface.h>
+#include <compositionengine/mock/NativeWindow.h>
 #include <compositionengine/mock/OutputLayer.h>
 #include <gtest/gtest.h>
 #include <renderengine/mock/RenderEngine.h>
-#include <system/window.h>
-#include <ui/ANativeObjectBase.h>
 
 #include "MockHWComposer.h"
 
@@ -34,123 +33,6 @@
 namespace {
 
 /* ------------------------------------------------------------------------
- * MockNativeWindow
- *
- * An intentionally simplified Mock which implements a minimal subset of the full
- * ANativeWindow interface.
- */
-
-class MockNativeWindow : public ANativeObjectBase<ANativeWindow, MockNativeWindow, RefBase> {
-public:
-    MockNativeWindow() {
-        ANativeWindow::setSwapInterval = &forwardSetSwapInterval;
-        ANativeWindow::dequeueBuffer = &forwardDequeueBuffer;
-        ANativeWindow::cancelBuffer = &forwardCancelBuffer;
-        ANativeWindow::queueBuffer = &forwardQueueBuffer;
-        ANativeWindow::query = &forwardQuery;
-        ANativeWindow::perform = &forwardPerform;
-
-        ANativeWindow::dequeueBuffer_DEPRECATED = &forwardDequeueBufferDeprecated;
-        ANativeWindow::cancelBuffer_DEPRECATED = &forwardCancelBufferDeprecated;
-        ANativeWindow::lockBuffer_DEPRECATED = &forwardLockBufferDeprecated;
-        ANativeWindow::queueBuffer_DEPRECATED = &forwardQueueBufferDeprecated;
-    }
-
-    MOCK_METHOD1(setSwapInterval, int(int));
-    MOCK_METHOD2(dequeueBuffer, int(struct ANativeWindowBuffer**, int*));
-    MOCK_METHOD2(cancelBuffer, int(struct ANativeWindowBuffer*, int));
-    MOCK_METHOD2(queueBuffer, int(struct ANativeWindowBuffer*, int));
-    MOCK_CONST_METHOD2(query, int(int, int*));
-    MOCK_METHOD1(connect, int(int));
-    MOCK_METHOD1(lockBuffer_DEPRECATED, int(struct ANativeWindowBuffer*));
-    MOCK_METHOD1(setBuffersFormat, int(PixelFormat));
-    MOCK_METHOD1(setBuffersDataSpace, int(ui::Dataspace));
-    MOCK_METHOD1(setUsage, int(uint64_t));
-
-    static void unexpectedCall(...) { LOG_ALWAYS_FATAL("Unexpected ANativeWindow API call"); }
-
-    static int forwardSetSwapInterval(ANativeWindow* window, int interval) {
-        return getSelf(window)->setSwapInterval(interval);
-    }
-
-    static int forwardDequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer,
-                                    int* fenceFd) {
-        return getSelf(window)->dequeueBuffer(buffer, fenceFd);
-    }
-
-    static int forwardCancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer,
-                                   int fenceFd) {
-        return getSelf(window)->cancelBuffer(buffer, fenceFd);
-    }
-
-    static int forwardQueueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
-        return getSelf(window)->queueBuffer(buffer, fenceFd);
-    }
-
-    static int forwardQuery(const ANativeWindow* window, int what, int* value) {
-        return getSelf(window)->query(what, value);
-    }
-
-    static int forwardPerform(ANativeWindow* window, int operation, ...) {
-        va_list args;
-        va_start(args, operation);
-        int result = NO_ERROR;
-        switch (operation) {
-            case NATIVE_WINDOW_API_CONNECT: {
-                int api = va_arg(args, int);
-                result = getSelf(window)->connect(api);
-                break;
-            }
-            case NATIVE_WINDOW_SET_BUFFERS_FORMAT: {
-                PixelFormat format = va_arg(args, PixelFormat);
-                result = getSelf(window)->setBuffersFormat(format);
-                break;
-            }
-            case NATIVE_WINDOW_SET_BUFFERS_DATASPACE: {
-                ui::Dataspace dataspace = static_cast<ui::Dataspace>(va_arg(args, int));
-                result = getSelf(window)->setBuffersDataSpace(dataspace);
-                break;
-            }
-            case NATIVE_WINDOW_SET_USAGE: {
-                // Note: Intentionally widens usage from 32 to 64 bits so we
-                // just have one implementation.
-                uint64_t usage = va_arg(args, uint32_t);
-                result = getSelf(window)->setUsage(usage);
-                break;
-            }
-            case NATIVE_WINDOW_SET_USAGE64: {
-                uint64_t usage = va_arg(args, uint64_t);
-                result = getSelf(window)->setUsage(usage);
-                break;
-            }
-            default:
-                LOG_ALWAYS_FATAL("Unexpected operation %d", operation);
-                break;
-        }
-
-        va_end(args);
-        return result;
-    }
-
-    static int forwardDequeueBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer** buffer) {
-        int ignoredFenceFd = -1;
-        return getSelf(window)->dequeueBuffer(buffer, &ignoredFenceFd);
-    }
-
-    static int forwardCancelBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer* buffer) {
-        return getSelf(window)->cancelBuffer(buffer, -1);
-    }
-
-    static int forwardLockBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer* buffer) {
-        return getSelf(window)->lockBuffer_DEPRECATED(buffer);
-    }
-
-    static int forwardQueueBufferDeprecated(ANativeWindow* window, ANativeWindowBuffer* buffer) {
-        return getSelf(window)->queueBuffer(buffer, -1);
-    }
-};
-
-/* ------------------------------------------------------------------------
  * RenderSurfaceTest
  */
 
@@ -175,6 +57,8 @@
         EXPECT_CALL(mDisplay, getName()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_NAME));
         EXPECT_CALL(mCompositionEngine, getHwComposer).WillRepeatedly(ReturnRef(mHwComposer));
         EXPECT_CALL(mCompositionEngine, getRenderEngine).WillRepeatedly(ReturnRef(mRenderEngine));
+        EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL))
+                .WillRepeatedly(Return(NO_ERROR));
     }
     ~RenderSurfaceTest() override = default;
 
@@ -182,7 +66,7 @@
     StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
     StrictMock<mock::CompositionEngine> mCompositionEngine;
     StrictMock<mock::Display> mDisplay;
-    sp<MockNativeWindow> mNativeWindow = new StrictMock<MockNativeWindow>();
+    sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>();
     sp<mock::DisplaySurface> mDisplaySurface = new StrictMock<mock::DisplaySurface>();
     impl::RenderSurface mSurface{mCompositionEngine, mDisplay,
                                  RenderSurfaceCreationArgs{DEFAULT_DISPLAY_WIDTH,