CE: Add test coverage for Output::composeSurfaces
As part of adding coverage, `PrintTo` and `operator==` were defined for
both RenderEngine::DisplaySettings and RenderEngine::LayerSettings so
that Google Test could use them.
Bug: 144115950
Test: atest libcompositionengine_test
Change-Id: Ia22c822f705e890435e81c0b75b4986afde49317
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 08b8818..d87389f 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -42,8 +42,11 @@
using testing::_;
using testing::ByMove;
using testing::DoAll;
+using testing::ElementsAreArray;
using testing::Eq;
using testing::InSequence;
+using testing::Invoke;
+using testing::IsEmpty;
using testing::Mock;
using testing::Property;
using testing::Ref;
@@ -2438,8 +2441,6 @@
mOutput.devOptRepaintFlash(mRefreshArgs);
}
-// TODO(b/144060211) - Add coverage
-
/*
* Output::finishFrame()
*/
@@ -2667,13 +2668,7 @@
*/
struct OutputComposeSurfacesTest : public testing::Test {
- static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
- static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::DISPLAY_P3;
-
- static const Rect kDefaultOutputFrame;
- static const Rect kDefaultOutputViewport;
- static const Rect kDefaultOutputScissor;
- static const mat4 kDefaultColorTransformMat;
+ using TestType = OutputComposeSurfacesTest;
struct OutputPartialMock : public OutputPartialMockBase {
// Sets up the helper functions called by the function under test to use
@@ -2691,84 +2686,404 @@
std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
- mOutput.editState().frame = kDefaultOutputFrame;
- mOutput.editState().viewport = kDefaultOutputViewport;
- mOutput.editState().scissor = kDefaultOutputScissor;
- mOutput.editState().transform = ui::Transform{kDefaultOutputOrientation};
- mOutput.editState().orientation = kDefaultOutputOrientation;
- mOutput.editState().dataspace = kDefaultOutputDataspace;
- mOutput.editState().colorTransformMatrix = kDefaultColorTransformMat;
- mOutput.editState().isSecure = true;
- mOutput.editState().needsFiltering = false;
- mOutput.editState().usesClientComposition = true;
- mOutput.editState().usesDeviceComposition = false;
+ mOutput.mState.frame = kDefaultOutputFrame;
+ mOutput.mState.viewport = kDefaultOutputViewport;
+ mOutput.mState.scissor = kDefaultOutputScissor;
+ mOutput.mState.transform = ui::Transform{kDefaultOutputOrientation};
+ mOutput.mState.orientation = kDefaultOutputOrientation;
+ mOutput.mState.dataspace = kDefaultOutputDataspace;
+ mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
+ mOutput.mState.isSecure = false;
+ mOutput.mState.needsFiltering = false;
+ mOutput.mState.usesClientComposition = true;
+ mOutput.mState.usesDeviceComposition = false;
- EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
- EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
- .WillRepeatedly(Return(&mOutputLayer1));
- EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
- .WillRepeatedly(Return(&mOutputLayer2));
EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
EXPECT_CALL(mCompositionEngine, getTimeStats())
.WillRepeatedly(ReturnRef(*mTimeStats.get()));
+ EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
+ .WillRepeatedly(ReturnRef(kHdrCapabilities));
}
+ struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
+ auto execute() {
+ getInstance()->mReadyFence = getInstance()->mOutput.composeSurfaces(kDebugRegion);
+ return nextState<FenceCheckState>();
+ }
+ };
+
+ struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
+ void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
+
+ void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
+ };
+
+ // Call this member function to start using the mini-DSL defined above.
+ [[nodiscard]] auto verify() { return ExecuteState::make(this); }
+
+ static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
+ static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
+ static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
+ static constexpr float kDefaultMaxLuminance = 0.9f;
+ static constexpr float kDefaultAvgLuminance = 0.7f;
+ static constexpr float kDefaultMinLuminance = 0.1f;
+
+ static const Rect kDefaultOutputFrame;
+ static const Rect kDefaultOutputViewport;
+ static const Rect kDefaultOutputScissor;
+ static const mat4 kDefaultColorTransformMat;
+
+ static const Region kDebugRegion;
+ static const HdrCapabilities kHdrCapabilities;
+
StrictMock<mock::CompositionEngine> mCompositionEngine;
StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
// TODO: make this is a proper mock.
std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
- StrictMock<mock::OutputLayer> mOutputLayer1;
- StrictMock<mock::OutputLayer> mOutputLayer2;
StrictMock<OutputPartialMock> mOutput;
sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
+
+ std::optional<base::unique_fd> mReadyFence;
};
const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
const Rect OutputComposeSurfacesTest::kDefaultOutputScissor{1009, 1010, 1011, 1012};
const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5};
-
-// TODO(b/121291683): Expand unit test coverage for composeSurfaces beyond these
-// basic tests.
+const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
+const HdrCapabilities OutputComposeSurfacesTest::
+ kHdrCapabilities{{},
+ OutputComposeSurfacesTest::kDefaultMaxLuminance,
+ OutputComposeSurfacesTest::kDefaultAvgLuminance,
+ OutputComposeSurfacesTest::kDefaultMinLuminance};
TEST_F(OutputComposeSurfacesTest, doesNothingIfNoClientComposition) {
- mOutput.editState().usesClientComposition = false;
+ mOutput.mState.usesClientComposition = false;
- Region debugRegion;
- std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(debugRegion);
- EXPECT_TRUE(readyFence);
+ verify().execute().expectAFenceWasReturned();
}
-TEST_F(OutputComposeSurfacesTest, worksIfNoClientLayersQueued) {
- const Region kDebugRegion{Rect{100, 101, 102, 103}};
+TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFails) {
+ EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{}));
+ EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
+ .WillRepeatedly(Return());
- constexpr float kDefaultMaxLuminance = 1.0f;
- constexpr float kDefaultAvgLuminance = 0.7f;
- constexpr float kDefaultMinLuminance = 0.1f;
- HdrCapabilities HdrCapabilities{{},
- kDefaultMaxLuminance,
- kDefaultAvgLuminance,
- kDefaultMinLuminance};
+ EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
- EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillOnce(Return(false));
- EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).Times(1);
+ verify().execute().expectNoFenceWasReturned();
+}
- EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillOnce(Return(true));
- EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities()).WillOnce(ReturnRef(HdrCapabilities));
+TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
+ EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{}));
+ EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
+ .WillRepeatedly(Return());
- EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
+ EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
+ EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
+ .WillRepeatedly(Return(NO_ERROR));
- EXPECT_CALL(mOutput, getSkipColorTransform()).WillOnce(Return(false));
- EXPECT_CALL(mOutput, generateClientCompositionRequests(false, _, _)).Times(1);
- EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)).Times(1);
- EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(1);
- EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false)).Times(1);
+ verify().execute().expectAFenceWasReturned();
+}
- std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(kDebugRegion);
- EXPECT_TRUE(readyFence);
+TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
+ renderengine::LayerSettings r1;
+ renderengine::LayerSettings r2;
+
+ r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
+ r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
+
+ EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{r1}));
+ EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
+ .WillRepeatedly(
+ Invoke([&](const Region&,
+ std::vector<renderengine::LayerSettings>& clientCompositionLayers) {
+ clientCompositionLayers.emplace_back(r2);
+ }));
+
+ EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
+ EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAreArray({r1, r2}), _, true, _, _))
+ .WillRepeatedly(Return(NO_ERROR));
+
+ verify().execute().expectAFenceWasReturned();
+}
+
+struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
+ OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
+ .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{}));
+ EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
+ .WillRepeatedly(Return());
+ EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
+ }
+
+ struct MixedCompositionState
+ : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
+ auto ifMixedCompositionIs(bool used) {
+ getInstance()->mOutput.mState.usesDeviceComposition = used;
+ return nextState<OutputUsesHdrState>();
+ }
+ };
+
+ struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
+ auto andIfUsesHdr(bool used) {
+ EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
+ .WillOnce(Return(used));
+ return nextState<SkipColorTransformState>();
+ }
+ };
+
+ struct SkipColorTransformState
+ : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
+ auto andIfSkipColorTransform(bool skip) {
+ // May be called zero or one times.
+ EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
+ .WillRepeatedly(Return(skip));
+ return nextState<ExpectDisplaySettingsState>();
+ }
+ };
+
+ struct ExpectDisplaySettingsState
+ : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
+ auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
+ EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
+ .WillOnce(Return(NO_ERROR));
+ return nextState<ExecuteState>();
+ }
+ };
+
+ // Call this member function to start using the mini-DSL defined above.
+ [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
+};
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
+ verify().ifMixedCompositionIs(true)
+ .andIfUsesHdr(true)
+ .andIfSkipColorTransform(false)
+ .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
+ kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+ Region::INVALID_REGION, kDefaultOutputOrientation})
+ .execute()
+ .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
+ verify().ifMixedCompositionIs(true)
+ .andIfUsesHdr(false)
+ .andIfSkipColorTransform(false)
+ .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
+ kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+ Region::INVALID_REGION, kDefaultOutputOrientation})
+ .execute()
+ .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
+ verify().ifMixedCompositionIs(false)
+ .andIfUsesHdr(true)
+ .andIfSkipColorTransform(false)
+ .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
+ kDefaultMaxLuminance, kDefaultOutputDataspace,
+ kDefaultColorTransformMat, Region::INVALID_REGION,
+ kDefaultOutputOrientation})
+ .execute()
+ .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
+ verify().ifMixedCompositionIs(false)
+ .andIfUsesHdr(false)
+ .andIfSkipColorTransform(false)
+ .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
+ kDefaultMaxLuminance, kDefaultOutputDataspace,
+ kDefaultColorTransformMat, Region::INVALID_REGION,
+ kDefaultOutputOrientation})
+ .execute()
+ .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
+ usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
+ verify().ifMixedCompositionIs(false)
+ .andIfUsesHdr(true)
+ .andIfSkipColorTransform(true)
+ .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
+ kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+ Region::INVALID_REGION, kDefaultOutputOrientation})
+ .execute()
+ .expectAFenceWasReturned();
+}
+
+struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
+ struct Layer {
+ Layer() {
+ EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(mLayer));
+ EXPECT_CALL(mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
+ }
+
+ StrictMock<mock::OutputLayer> mOutputLayer;
+ StrictMock<mock::Layer> mLayer;
+ LayerFECompositionState mLayerFEState;
+ };
+
+ OutputComposeSurfacesTest_HandlesProtectedContent() {
+ mLayer1.mLayerFEState.hasProtectedContent = false;
+ mLayer2.mLayerFEState.hasProtectedContent = false;
+
+ EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
+ EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
+ .WillRepeatedly(Return(&mLayer1.mOutputLayer));
+ EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
+ .WillRepeatedly(Return(&mLayer2.mOutputLayer));
+
+ EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
+
+ EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
+
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
+ .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{}));
+ EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
+ .WillRepeatedly(Return());
+ EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
+ EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
+ .WillRepeatedly(Return(NO_ERROR));
+ }
+
+ Layer mLayer1;
+ Layer mLayer2;
+};
+
+TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
+ mOutput.mState.isSecure = false;
+ mLayer2.mLayerFEState.hasProtectedContent = true;
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
+
+ mOutput.composeSurfaces(kDebugRegion);
+}
+
+TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
+ mOutput.mState.isSecure = true;
+ mLayer2.mLayerFEState.hasProtectedContent = true;
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+
+ mOutput.composeSurfaces(kDebugRegion);
+}
+
+TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
+ mOutput.mState.isSecure = true;
+ mLayer2.mLayerFEState.hasProtectedContent = false;
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
+ EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
+ EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
+ EXPECT_CALL(mRenderEngine, useProtectedContext(false));
+ EXPECT_CALL(*mRenderSurface, setProtected(false));
+
+ mOutput.composeSurfaces(kDebugRegion);
+}
+
+TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
+ mOutput.mState.isSecure = true;
+ mLayer2.mLayerFEState.hasProtectedContent = true;
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
+
+ // For this test, we also check the call order of key functions.
+ InSequence seq;
+
+ EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
+ EXPECT_CALL(mRenderEngine, useProtectedContext(true));
+ EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
+ EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
+ EXPECT_CALL(*mRenderSurface, setProtected(true));
+ // Must happen after setting the protected content state.
+ EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
+ EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
+
+ mOutput.composeSurfaces(kDebugRegion);
+}
+
+TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
+ mOutput.mState.isSecure = true;
+ mLayer2.mLayerFEState.hasProtectedContent = true;
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
+ EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
+ EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
+
+ mOutput.composeSurfaces(kDebugRegion);
+}
+
+TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
+ mOutput.mState.isSecure = true;
+ mLayer2.mLayerFEState.hasProtectedContent = true;
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
+ EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
+ EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
+ EXPECT_CALL(mRenderEngine, useProtectedContext(true));
+
+ mOutput.composeSurfaces(kDebugRegion);
+}
+
+TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
+ mOutput.mState.isSecure = true;
+ mLayer2.mLayerFEState.hasProtectedContent = true;
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
+ EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
+ EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
+ EXPECT_CALL(*mRenderSurface, setProtected(true));
+
+ mOutput.composeSurfaces(kDebugRegion);
+}
+
+TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
+ mOutput.mState.isSecure = true;
+ mLayer2.mLayerFEState.hasProtectedContent = true;
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
+ EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
+ EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
+ EXPECT_CALL(mRenderEngine, useProtectedContext(true));
+
+ mOutput.composeSurfaces(kDebugRegion);
+}
+
+struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
+ OutputComposeSurfacesTest_SetsExpensiveRendering() {
+ EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
+ EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
+ EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
+ .WillRepeatedly(Return());
+ EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
+ }
+};
+
+TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
+ mOutput.mState.dataspace = kExpensiveOutputDataspace;
+
+ EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
+ .WillOnce(Return(std::vector<renderengine::LayerSettings>{}));
+
+ // For this test, we also check the call order of key functions.
+ InSequence seq;
+
+ EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
+ EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
+ EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
+
+ mOutput.composeSurfaces(kDebugRegion);
}
/*