SF: Abstract and mock HWC2::Layer

This allows tests to be written without creating a real HWC2::Layer.

Test: atest libsurfaceflinger_unittest libcompositionengine_test
Bug: 121291683
Change-Id: I6091329973bf765d3a8ef387f45565f341acdd39
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index f5376a5..e86d35d 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -91,6 +91,7 @@
         "tests/DisplayTest.cpp",
         "tests/HwcBufferCacheTest.cpp",
         "tests/LayerTest.cpp",
+        "tests/MockHWC2.cpp",
         "tests/MockHWComposer.cpp",
         "tests/OutputTest.cpp",
         "tests/OutputLayerTest.cpp",
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.cpp b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.cpp
new file mode 100644
index 0000000..8c10341
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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 "MockHWC2.h"
+
+namespace HWC2 {
+
+// This will go away once HWC2::Layer is moved into the "backend" library
+Layer::~Layer() = default;
+
+namespace mock {
+
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
+Layer::Layer() = default;
+Layer::~Layer() = default;
+
+} // namespace mock
+} // namespace HWC2
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
new file mode 100644
index 0000000..7fd6541
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
@@ -0,0 +1,63 @@
+/*
+ * 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 <ui/Fence.h>
+#include <ui/FloatRect.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicTypes.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/Transform.h>
+
+#include "DisplayHardware/HWC2.h"
+
+namespace HWC2 {
+namespace mock {
+
+class Layer : public HWC2::Layer {
+public:
+    Layer();
+    ~Layer() override;
+
+    MOCK_CONST_METHOD0(getId, hwc2_layer_t());
+
+    MOCK_METHOD2(setCursorPosition, Error(int32_t, int32_t));
+    MOCK_METHOD3(setBuffer,
+                 Error(uint32_t, const android::sp<android::GraphicBuffer>&,
+                       const android::sp<android::Fence>&));
+    MOCK_METHOD1(setSurfaceDamage, Error(const android::Region&));
+    MOCK_METHOD1(setBlendMode, Error(BlendMode));
+    MOCK_METHOD1(setColor, Error(hwc_color_t));
+    MOCK_METHOD1(setCompositionType, Error(Composition));
+    MOCK_METHOD1(setDataspace, Error(android::ui::Dataspace));
+    MOCK_METHOD2(setPerFrameMetadata, Error(const int32_t, const android::HdrMetadata&));
+    MOCK_METHOD1(setDisplayFrame, Error(const android::Rect&));
+    MOCK_METHOD1(setPlaneAlpha, Error(float));
+    MOCK_METHOD1(setSidebandStream, Error(const native_handle_t*));
+    MOCK_METHOD1(setSourceCrop, Error(const android::FloatRect&));
+    MOCK_METHOD1(setTransform, Error(Transform));
+    MOCK_METHOD1(setVisibleRegion, Error(const android::Region&));
+    MOCK_METHOD1(setZOrder, Error(uint32_t));
+    MOCK_METHOD2(setInfo, Error(uint32_t, uint32_t));
+
+    MOCK_METHOD1(setColorTransform, Error(const android::mat4&));
+};
+
+} // namespace mock
+} // namespace HWC2
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 68e7876..bca0abc 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -308,8 +308,7 @@
     return static_cast<Error>(intError);
 }
 
-Error Display::createLayer(Layer** outLayer)
-{
+Error Display::createLayer(HWC2::Layer** outLayer) {
     if (!outLayer) {
         return Error::BadParameter;
     }
@@ -320,15 +319,13 @@
         return error;
     }
 
-    auto layer = std::make_unique<Layer>(
-            mComposer, mCapabilities, mId, layerId);
+    auto layer = std::make_unique<impl::Layer>(mComposer, mCapabilities, mId, layerId);
     *outLayer = layer.get();
     mLayers.emplace(layerId, std::move(layer));
     return Error::None;
 }
 
-Error Display::destroyLayer(Layer* layer)
-{
+Error Display::destroyLayer(HWC2::Layer* layer) {
     if (!layer) {
         return Error::BadParameter;
     }
@@ -388,9 +385,7 @@
     return Error::None;
 }
 
-Error Display::getChangedCompositionTypes(
-        std::unordered_map<Layer*, Composition>* outTypes)
-{
+Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) {
     std::vector<Hwc2::Layer> layerIds;
     std::vector<Hwc2::IComposerClient::Composition> types;
     auto intError = mComposer.getChangedCompositionTypes(
@@ -492,8 +487,7 @@
 }
 
 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
-        std::unordered_map<Layer*, LayerRequest>* outLayerRequests)
-{
+                           std::unordered_map<HWC2::Layer*, LayerRequest>* outLayerRequests) {
     uint32_t intDisplayRequests;
     std::vector<Hwc2::Layer> layerIds;
     std::vector<uint32_t> layerRequests;
@@ -574,9 +568,7 @@
     return static_cast<Error>(intError);
 }
 
-Error Display::getReleaseFences(
-        std::unordered_map<Layer*, sp<Fence>>* outFences) const
-{
+Error Display::getReleaseFences(std::unordered_map<HWC2::Layer*, sp<Fence>>* outFences) const {
     std::vector<Hwc2::Layer> layerIds;
     std::vector<int> fenceFds;
     auto intError = mComposer.getReleaseFences(mId, &layerIds, &fenceFds);
@@ -586,7 +578,7 @@
         return error;
     }
 
-    std::unordered_map<Layer*, sp<Fence>> releaseFences;
+    std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
     releaseFences.reserve(numElements);
     for (uint32_t element = 0; element < numElements; ++element) {
         auto layer = getLayerById(layerIds[element]);
@@ -787,8 +779,7 @@
 
 // Other Display methods
 
-Layer* Display::getLayerById(hwc2_layer_t id) const
-{
+HWC2::Layer* Display::getLayerById(hwc2_layer_t id) const {
     if (mLayers.count(id) == 0) {
         return nullptr;
     }
@@ -799,6 +790,10 @@
 
 // Layer methods
 
+Layer::~Layer() = default;
+
+namespace impl {
+
 Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
              hwc2_display_t displayId, hwc2_layer_t layerId)
   : mComposer(composer),
@@ -817,15 +812,6 @@
     ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
             " failed: %s (%d)", mDisplayId, mId, to_string(error).c_str(),
             intError);
-    if (mLayerDestroyedListener) {
-        mLayerDestroyedListener(this);
-    }
-}
-
-void Layer::setLayerDestroyedListener(std::function<void(Layer*)> listener) {
-    LOG_ALWAYS_FATAL_IF(mLayerDestroyedListener && listener,
-            "Attempt to set layer destroyed listener multiple times");
-    mLayerDestroyedListener = listener;
 }
 
 Error Layer::setCursorPosition(int32_t x, int32_t y)
@@ -1033,4 +1019,6 @@
     auto intError = mComposer.setLayerColorTransform(mDisplayId, mId, matrix.asArray());
     return static_cast<Error>(intError);
 }
+
+} // namespace impl
 } // namespace HWC2
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index c1f481a..70358a0 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -364,52 +364,73 @@
 };
 } // namespace impl
 
+class Layer {
+public:
+    virtual ~Layer();
+
+    virtual hwc2_layer_t getId() const = 0;
+
+    [[clang::warn_unused_result]] virtual Error setCursorPosition(int32_t x, int32_t y) = 0;
+    [[clang::warn_unused_result]] virtual Error setBuffer(
+            uint32_t slot, const android::sp<android::GraphicBuffer>& buffer,
+            const android::sp<android::Fence>& acquireFence) = 0;
+    [[clang::warn_unused_result]] virtual Error setSurfaceDamage(const android::Region& damage) = 0;
+
+    [[clang::warn_unused_result]] virtual Error setBlendMode(BlendMode mode) = 0;
+    [[clang::warn_unused_result]] virtual Error setColor(hwc_color_t color) = 0;
+    [[clang::warn_unused_result]] virtual Error setCompositionType(Composition type) = 0;
+    [[clang::warn_unused_result]] virtual Error setDataspace(android::ui::Dataspace dataspace) = 0;
+    [[clang::warn_unused_result]] virtual Error setPerFrameMetadata(
+            const int32_t supportedPerFrameMetadata, const android::HdrMetadata& metadata) = 0;
+    [[clang::warn_unused_result]] virtual Error setDisplayFrame(const android::Rect& frame) = 0;
+    [[clang::warn_unused_result]] virtual Error setPlaneAlpha(float alpha) = 0;
+    [[clang::warn_unused_result]] virtual Error setSidebandStream(
+            const native_handle_t* stream) = 0;
+    [[clang::warn_unused_result]] virtual Error setSourceCrop(const android::FloatRect& crop) = 0;
+    [[clang::warn_unused_result]] virtual Error setTransform(Transform transform) = 0;
+    [[clang::warn_unused_result]] virtual Error setVisibleRegion(const android::Region& region) = 0;
+    [[clang::warn_unused_result]] virtual Error setZOrder(uint32_t z) = 0;
+    [[clang::warn_unused_result]] virtual Error setInfo(uint32_t type, uint32_t appId) = 0;
+
+    // Composer HAL 2.3
+    [[clang::warn_unused_result]] virtual Error setColorTransform(const android::mat4& matrix) = 0;
+};
+
+namespace impl {
+
 // Convenience C++ class to access hwc2_device_t Layer functions directly.
-class Layer
-{
+
+class Layer : public HWC2::Layer {
 public:
     Layer(android::Hwc2::Composer& composer,
           const std::unordered_set<Capability>& capabilities,
           hwc2_display_t displayId, hwc2_layer_t layerId);
-    ~Layer();
+    ~Layer() override;
 
-    hwc2_layer_t getId() const { return mId; }
+    hwc2_layer_t getId() const override { return mId; }
 
-    // Register a listener to be notified when the layer is destroyed. When the
-    // listener function is called, the Layer will be in the process of being
-    // destroyed, so it's not safe to call methods on it.
-    void setLayerDestroyedListener(std::function<void(Layer*)> listener);
+    Error setCursorPosition(int32_t x, int32_t y) override;
+    Error setBuffer(uint32_t slot, const android::sp<android::GraphicBuffer>& buffer,
+                    const android::sp<android::Fence>& acquireFence) override;
+    Error setSurfaceDamage(const android::Region& damage) override;
 
-    [[clang::warn_unused_result]] Error setCursorPosition(int32_t x, int32_t y);
-    [[clang::warn_unused_result]] Error setBuffer(uint32_t slot,
-            const android::sp<android::GraphicBuffer>& buffer,
-            const android::sp<android::Fence>& acquireFence);
-    [[clang::warn_unused_result]] Error setSurfaceDamage(
-            const android::Region& damage);
-
-    [[clang::warn_unused_result]] Error setBlendMode(BlendMode mode);
-    [[clang::warn_unused_result]] Error setColor(hwc_color_t color);
-    [[clang::warn_unused_result]] Error setCompositionType(Composition type);
-    [[clang::warn_unused_result]] Error setDataspace(
-            android::ui::Dataspace dataspace);
-    [[clang::warn_unused_result]] Error setPerFrameMetadata(
-            const int32_t supportedPerFrameMetadata,
-            const android::HdrMetadata& metadata);
-    [[clang::warn_unused_result]] Error setDisplayFrame(
-            const android::Rect& frame);
-    [[clang::warn_unused_result]] Error setPlaneAlpha(float alpha);
-    [[clang::warn_unused_result]] Error setSidebandStream(
-            const native_handle_t* stream);
-    [[clang::warn_unused_result]] Error setSourceCrop(
-            const android::FloatRect& crop);
-    [[clang::warn_unused_result]] Error setTransform(Transform transform);
-    [[clang::warn_unused_result]] Error setVisibleRegion(
-            const android::Region& region);
-    [[clang::warn_unused_result]] Error setZOrder(uint32_t z);
-    [[clang::warn_unused_result]] Error setInfo(uint32_t type, uint32_t appId);
+    Error setBlendMode(BlendMode mode) override;
+    Error setColor(hwc_color_t color) override;
+    Error setCompositionType(Composition type) override;
+    Error setDataspace(android::ui::Dataspace dataspace) override;
+    Error setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
+                              const android::HdrMetadata& metadata) override;
+    Error setDisplayFrame(const android::Rect& frame) override;
+    Error setPlaneAlpha(float alpha) override;
+    Error setSidebandStream(const native_handle_t* stream) override;
+    Error setSourceCrop(const android::FloatRect& crop) override;
+    Error setTransform(Transform transform) override;
+    Error setVisibleRegion(const android::Region& region) override;
+    Error setZOrder(uint32_t z) override;
+    Error setInfo(uint32_t type, uint32_t appId) override;
 
     // Composer HAL 2.3
-    [[clang::warn_unused_result]] Error setColorTransform(const android::mat4& matrix);
+    Error setColorTransform(const android::mat4& matrix) override;
 
 private:
     // These are references to data owned by HWC2::Device, which will outlive
@@ -422,10 +443,11 @@
     hwc2_layer_t mId;
     android::ui::Dataspace mDataSpace = android::ui::Dataspace::UNKNOWN;
     android::HdrMetadata mHdrMetadata;
-    std::function<void(Layer*)> mLayerDestroyedListener;
     android::mat4 mColorMatrix;
 };
 
+} // namespace impl
+
 } // namespace HWC2
 
 #endif // ANDROID_SF_HWC2_H