diff options
author | Alec Mouri <alecmouri@google.com> | 2021-07-19 17:03:28 -0700 |
---|---|---|
committer | Alec Mouri <alecmouri@google.com> | 2021-07-20 14:03:53 -0700 |
commit | c83408ad4fb314b466ba4637f208f924a7044563 (patch) | |
tree | e2b4b83655bfb51ee09b66cc6e49480d72666f94 | |
parent | 5ede32f26da962bf50970e2827cb294fbd2b281a (diff) | |
download | native-c83408ad4fb314b466ba4637f208f924a7044563.tar.gz |
Fix caching flickering for unsecure displays
Rendering a cached set needs to respect the secure mode for the display.
Otherwise, compositing a secure layer onto an unsecure display would
incorrectly leak information in a cached set.
Bug: 193103018
Test: Chrome in incognito mode and verify that both screenrecord and
simulating a virtual insecure display does not leak Chrome's content.
Change-Id: I6d43e1c7de41f113477d9928b91ee0b286249751
-rw-r--r-- | services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp | 72 |
2 files changed, 70 insertions, 4 deletions
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp index b24274e731..f80ec223c1 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp @@ -175,7 +175,7 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te LayerFE::ClientCompositionTargetSettings targetSettings{ .clip = Region(viewport), .needsFiltering = false, - .isSecure = true, + .isSecure = outputState.isSecure, .supportsProtectedContent = false, .clearRegion = clearRegion, .viewport = viewport, diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp index b05a594a92..b765337410 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp @@ -51,6 +51,15 @@ MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "" return expectedBlurSetting == arg.blurSetting; } + +MATCHER_P(ClientCompositionTargetSettingsSecureEq, expectedSecureSetting, "") { + *result_listener << "ClientCompositionTargetSettings' SecureSettings aren't equal \n"; + *result_listener << "expected " << expectedSecureSetting << "\n"; + *result_listener << "actual " << arg.isSecure << "\n"; + + return expectedSecureSetting == arg.isSecure; +} + static const ui::Size kOutputSize = ui::Size(1, 1); class CachedSetTest : public testing::Test { @@ -315,7 +324,7 @@ TEST_F(CachedSetTest, updateAge_BufferUpdate) { EXPECT_EQ(0u, cachedSet.getAge()); } -TEST_F(CachedSetTest, render) { +TEST_F(CachedSetTest, renderUnsecureOutput) { // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0) CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get(); sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE; @@ -348,9 +357,66 @@ TEST_F(CachedSetTest, render) { return NO_ERROR; }; - EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1)); - EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2)); + EXPECT_CALL(*layerFE1, + prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(false))) + .WillOnce(Return(clientCompList1)); + EXPECT_CALL(*layerFE2, + prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(false))) + .WillOnce(Return(clientCompList2)); + EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers)); + mOutputState.isSecure = false; + cachedSet.render(mRenderEngine, mTexturePool, mOutputState); + expectReadyBuffer(cachedSet); + + EXPECT_EQ(mOutputState.framebufferSpace, cachedSet.getOutputSpace()); + EXPECT_EQ(Rect(kOutputSize.width, kOutputSize.height), cachedSet.getTextureBounds()); + + // Now check that appending a new cached set properly cleans up RenderEngine resources. + CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get(); + cachedSet.append(CachedSet(layer3)); +} + +TEST_F(CachedSetTest, renderSecureOutput) { + // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0) + CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get(); + sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE; + CachedSet::Layer& layer2 = *mTestLayers[2]->cachedSetLayer.get(); + sp<mock::LayerFE> layerFE2 = mTestLayers[2]->layerFE; + + CachedSet cachedSet(layer1); + cachedSet.append(CachedSet(layer2)); + + std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1; + clientCompList1.push_back({}); + clientCompList1[0].alpha = 0.5f; + + std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2; + clientCompList2.push_back({}); + clientCompList2[0].alpha = 0.75f; + + const auto drawLayers = [&](const renderengine::DisplaySettings& displaySettings, + const std::vector<const renderengine::LayerSettings*>& layers, + const std::shared_ptr<renderengine::ExternalTexture>&, const bool, + base::unique_fd&&, base::unique_fd*) -> size_t { + EXPECT_EQ(mOutputState.framebufferSpace.content, displaySettings.physicalDisplay); + EXPECT_EQ(mOutputState.layerStackSpace.content, displaySettings.clip); + EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.orientation), + displaySettings.orientation); + EXPECT_EQ(0.5f, layers[0]->alpha); + EXPECT_EQ(0.75f, layers[1]->alpha); + EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace); + + return NO_ERROR; + }; + + EXPECT_CALL(*layerFE1, + prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(true))) + .WillOnce(Return(clientCompList1)); + EXPECT_CALL(*layerFE2, + prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(true))) + .WillOnce(Return(clientCompList2)); EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers)); + mOutputState.isSecure = true; cachedSet.render(mRenderEngine, mTexturePool, mOutputState); expectReadyBuffer(cachedSet); |