Merge "Add isProtected flag to Output" into main
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 98c4af4..6e60839 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
@@ -42,6 +42,10 @@
// True if this display should be considered secure
bool isSecure = false;
+ // True if this display should be considered protected, as in this display should render DRM
+ // content.
+ bool isProtected = false;
+
// Optional pointer to the power advisor interface, if one is needed for
// this display.
Hwc2::PowerAdvisor* powerAdvisor = nullptr;
@@ -73,6 +77,11 @@
return *this;
}
+ DisplayCreationArgsBuilder& setIsProtected(bool isProtected) {
+ mArgs.isProtected = isProtected;
+ return *this;
+ }
+
DisplayCreationArgsBuilder& setPowerAdvisor(Hwc2::PowerAdvisor* powerAdvisor) {
mArgs.powerAdvisor = powerAdvisor;
return *this;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index ccff1ec..a1d6132 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -97,7 +97,7 @@
const bool isSecure;
// If set to true, the target buffer has protected content support.
- const bool supportsProtectedContent;
+ const bool isProtected;
// Viewport of the target being rendered to. This is used to determine
// the shadow light position.
@@ -167,8 +167,7 @@
static inline bool operator==(const LayerFE::ClientCompositionTargetSettings& lhs,
const LayerFE::ClientCompositionTargetSettings& rhs) {
return lhs.clip.hasSameRects(rhs.clip) && lhs.needsFiltering == rhs.needsFiltering &&
- lhs.isSecure == rhs.isSecure &&
- lhs.supportsProtectedContent == rhs.supportsProtectedContent &&
+ lhs.isSecure == rhs.isSecure && lhs.isProtected == rhs.isProtected &&
lhs.viewport == rhs.viewport && lhs.dataspace == rhs.dataspace &&
lhs.realContentIsVisible == rhs.realContentIsVisible &&
lhs.clearContent == rhs.clearContent;
@@ -189,7 +188,7 @@
PrintTo(settings.clip, os);
*os << "\n .needsFiltering = " << settings.needsFiltering;
*os << "\n .isSecure = " << settings.isSecure;
- *os << "\n .supportsProtectedContent = " << settings.supportsProtectedContent;
+ *os << "\n .isProtected = " << settings.isProtected;
*os << "\n .viewport = ";
PrintTo(settings.viewport, os);
*os << "\n .dataspace = ";
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index 692ed24..6b1c318 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -53,6 +53,9 @@
// If false, this output is not considered secure
bool isSecure{false};
+ // If false, this output is not considered protected
+ bool isProtected{false};
+
// If true, the current frame on this output uses client composition
bool usesClientComposition{false};
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 0475881..690d35f 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -57,6 +57,7 @@
mId = args.id;
mPowerAdvisor = args.powerAdvisor;
editState().isSecure = args.isSecure;
+ editState().isProtected = args.isProtected;
editState().displaySpace.setBounds(args.pixels);
setName(args.name);
}
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index e4d7578..c399224 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -1232,10 +1232,18 @@
auto& renderEngine = getCompositionEngine().getRenderEngine();
const bool supportsProtectedContent = renderEngine.supportsProtectedContent();
- // If we the display is secure, protected content support is enabled, and at
- // least one layer has protected content, we need to use a secure back
- // buffer.
- if (outputState.isSecure && supportsProtectedContent) {
+ bool isProtected;
+ if (FlagManager::getInstance().display_protected()) {
+ isProtected = outputState.isProtected;
+ } else {
+ isProtected = outputState.isSecure;
+ }
+
+ // We need to set the render surface as protected (DRM) if all the following conditions are met:
+ // 1. The display is protected (in legacy, check if the display is secure)
+ // 2. Protected content is supported
+ // 3. At least one layer has protected content.
+ if (isProtected && supportsProtectedContent) {
auto layers = getOutputLayersOrderedByZ();
bool needsProtected = std::any_of(layers.begin(), layers.end(), [](auto* layer) {
return layer->getLayerFE().getCompositionState()->hasProtectedContent;
@@ -1475,12 +1483,16 @@
BlurRegionsOnly
: LayerFE::ClientCompositionTargetSettings::BlurSetting::
Enabled);
+ bool isProtected = supportsProtectedContent;
+ if (FlagManager::getInstance().display_protected()) {
+ isProtected = outputState.isProtected && supportsProtectedContent;
+ }
compositionengine::LayerFE::ClientCompositionTargetSettings
targetSettings{.clip = clip,
.needsFiltering = layer->needsFiltering() ||
outputState.needsFiltering,
.isSecure = outputState.isSecure,
- .supportsProtectedContent = supportsProtectedContent,
+ .isProtected = isProtected,
.viewport = outputState.layerStackSpace.getContent(),
.dataspace = outputDataspace,
.realContentIsVisible = realContentIsVisible,
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index 579c6ba..869dda6 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -184,7 +184,7 @@
targetSettings{.clip = Region(viewport),
.needsFiltering = false,
.isSecure = outputState.isSecure,
- .supportsProtectedContent = false,
+ .isProtected = false,
.viewport = viewport,
.dataspace = outputDataspace,
.realContentIsVisible = true,
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 249c40b..950b05e 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -72,6 +72,7 @@
mRefreshRateSelector(std::move(args.refreshRateSelector)),
mHasDesiredModeTrace(concatId("HasDesiredMode"), false) {
mCompositionDisplay->editState().isSecure = args.isSecure;
+ mCompositionDisplay->editState().isProtected = args.isProtected;
mCompositionDisplay->createRenderSurface(
compositionengine::RenderSurfaceCreationArgsBuilder()
.setDisplayWidth(ANativeWindow_getWidth(args.nativeWindow.get()))
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 51c7be0..ac390cb 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -332,6 +332,7 @@
uint32_t height = 0;
std::string displayName;
bool isSecure = false;
+ bool isProtected = false;
// Refer to DisplayDevice::mRequestedRefreshRate, for virtual display only
Fps requestedRefreshRate;
@@ -353,6 +354,7 @@
int32_t sequenceId{0};
bool isSecure{false};
+ bool isProtected{false};
sp<ANativeWindow> nativeWindow;
sp<compositionengine::DisplaySurface> displaySurface;
ui::Rotation physicalOrientation{ui::ROTATION_0};
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
index f25619a..2dbcb84 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -208,9 +208,15 @@
// activeBuffer, then we need to return LayerSettings.
return;
}
- const bool blackOutLayer =
- (mSnapshot->hasProtectedContent && !targetSettings.supportsProtectedContent) ||
- ((mSnapshot->isSecure || mSnapshot->hasProtectedContent) && !targetSettings.isSecure);
+ bool blackOutLayer;
+ if (FlagManager::getInstance().display_protected()) {
+ blackOutLayer = (mSnapshot->hasProtectedContent && !targetSettings.isProtected) ||
+ (mSnapshot->isSecure && !targetSettings.isSecure);
+ } else {
+ blackOutLayer = (mSnapshot->hasProtectedContent && !targetSettings.isProtected) ||
+ ((mSnapshot->isSecure || mSnapshot->hasProtectedContent) &&
+ !targetSettings.isSecure);
+ }
const bool bufferCanBeUsedAsHwTexture =
mSnapshot->externalTexture->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
if (blackOutLayer || !bufferCanBeUsedAsHwTexture) {
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 6db39f1..c888ccc 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -374,10 +374,11 @@
constexpr bool kRegionSampling = true;
constexpr bool kGrayscale = false;
+ constexpr bool kIsProtected = false;
if (const auto fenceResult =
mFlinger.captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, buffer,
- kRegionSampling, kGrayscale, nullptr)
+ kRegionSampling, kGrayscale, kIsProtected, nullptr)
.get();
fenceResult.ok()) {
fenceResult.value()->waitForever(LOG_TAG);
diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp
index 57b0d5e..a4a5ce2 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.cpp
+++ b/services/surfaceflinger/ScreenCaptureOutput.cpp
@@ -32,6 +32,7 @@
bool>(args.compositionEngine, args.renderArea, args.colorProfile, args.regionSampling,
args.dimInGammaSpaceForEnhancedScreenshots);
output->editState().isSecure = args.renderArea.isSecure();
+ output->editState().isProtected = args.isProtected;
output->setCompositionEnabled(true);
output->setLayerFilter({args.layerStack});
output->setRenderSurface(std::make_unique<ScreenCaptureRenderSurface>(std::move(args.buffer)));
diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h
index fc095de..1c16308 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.h
+++ b/services/surfaceflinger/ScreenCaptureOutput.h
@@ -38,6 +38,7 @@
bool regionSampling;
bool treat170mAsSrgb;
bool dimInGammaSpaceForEnhancedScreenshots;
+ bool isProtected = false;
};
// ScreenCaptureOutput is used to compose a set of layers into a preallocated buffer.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1dcc19e..c4de02f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -565,6 +565,9 @@
// Display ID is assigned when virtual display is allocated by HWC.
DisplayDeviceState state;
state.isSecure = secure;
+ // Set display as protected when marked as secure to ensure no behavior change
+ // TODO (b/314820005): separate as a different arg when creating the display.
+ state.isProtected = secure;
state.displayName = displayName;
state.requestedRefreshRate = Fps::fromValue(requestedRefreshRate);
mCurrentState.displays.add(token, state);
@@ -3381,6 +3384,7 @@
.hwcDisplayId = hwcDisplayId,
.activeMode = std::move(activeMode)};
state.isSecure = true; // All physical displays are currently considered secure.
+ state.isProtected = true;
state.displayName = std::move(info.name);
mCurrentState.displays.add(token, state);
@@ -3412,6 +3416,7 @@
displayToken, compositionDisplay);
creationArgs.sequenceId = state.sequenceId;
creationArgs.isSecure = state.isSecure;
+ creationArgs.isProtected = state.isProtected;
creationArgs.displaySurface = displaySurface;
creationArgs.hasWideColorGamut = false;
creationArgs.supportedPerFrameMetadata = 0;
@@ -3543,6 +3548,7 @@
builder.setPixels(resolution);
builder.setIsSecure(state.isSecure);
+ builder.setIsProtected(state.isProtected);
builder.setPowerAdvisor(mPowerAdvisor.get());
builder.setName(state.displayName);
auto compositionDisplay = getCompositionEngine().createDisplay(builder.build());
@@ -7856,12 +7862,11 @@
})
.get();
}
-
+ const bool isProtected = hasProtectedLayer && allowProtected && supportsProtected;
const uint32_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_TEXTURE |
- (hasProtectedLayer && allowProtected && supportsProtected
- ? GRALLOC_USAGE_PROTECTED
- : GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+ (isProtected ? GRALLOC_USAGE_PROTECTED
+ : GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
sp<GraphicBuffer> buffer =
getFactory().createGraphicBuffer(bufferSize.getWidth(), bufferSize.getHeight(),
static_cast<android_pixel_format>(reqPixelFormat),
@@ -7881,14 +7886,15 @@
renderengine::impl::ExternalTexture::Usage::
WRITEABLE);
auto fence = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, texture,
- false /* regionSampling */, grayscale, captureListener);
+ false /* regionSampling */, grayscale, isProtected,
+ captureListener);
fence.get();
}
ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon(
RenderAreaFuture renderAreaFuture, GetLayerSnapshotsFunction getLayerSnapshots,
const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
- bool grayscale, const sp<IScreenCaptureListener>& captureListener) {
+ bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
auto future = mScheduler->schedule(
@@ -7907,8 +7913,9 @@
ftl::SharedFuture<FenceResult> renderFuture;
renderArea->render([&]() FTL_FAKE_GUARD(kMainThreadContext) {
- renderFuture = renderScreenImpl(renderArea, getLayerSnapshots, buffer,
- regionSampling, grayscale, captureResults);
+ renderFuture =
+ renderScreenImpl(renderArea, getLayerSnapshots, buffer, regionSampling,
+ grayscale, isProtected, captureResults);
});
if (captureListener) {
@@ -7936,7 +7943,7 @@
ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl(
std::shared_ptr<const RenderArea> renderArea, GetLayerSnapshotsFunction getLayerSnapshots,
const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
- bool grayscale, ScreenCaptureResults& captureResults) {
+ bool grayscale, bool isProtected, ScreenCaptureResults& captureResults) {
ATRACE_CALL();
auto layers = getLayerSnapshots();
@@ -8031,9 +8038,9 @@
};
auto present = [this, buffer = capturedBuffer, dataspace = captureResults.capturedDataspace,
- sdrWhitePointNits, displayBrightnessNits, grayscale, layerFEs = copyLayerFEs(),
- layerStack, regionSampling, renderArea = std::move(renderArea),
- renderIntent]() -> FenceResult {
+ sdrWhitePointNits, displayBrightnessNits, grayscale, isProtected,
+ layerFEs = copyLayerFEs(), layerStack, regionSampling,
+ renderArea = std::move(renderArea), renderIntent]() -> FenceResult {
std::unique_ptr<compositionengine::CompositionEngine> compositionEngine =
mFactory.createCompositionEngine();
compositionEngine->setRenderEngine(mRenderEngine.get());
@@ -8067,7 +8074,8 @@
.regionSampling = regionSampling,
.treat170mAsSrgb = mTreat170mAsSrgb,
.dimInGammaSpaceForEnhancedScreenshots =
- dimInGammaSpaceForEnhancedScreenshots});
+ dimInGammaSpaceForEnhancedScreenshots,
+ .isProtected = isProtected});
const float colorSaturation = grayscale ? 0 : 1;
compositionengine::CompositionRefreshArgs refreshArgs{
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c4af271..6909055 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -855,11 +855,11 @@
ftl::SharedFuture<FenceResult> captureScreenCommon(
RenderAreaFuture, GetLayerSnapshotsFunction,
const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling,
- bool grayscale, const sp<IScreenCaptureListener>&);
+ bool grayscale, bool isProtected, const sp<IScreenCaptureListener>&);
ftl::SharedFuture<FenceResult> renderScreenImpl(
std::shared_ptr<const RenderArea>, GetLayerSnapshotsFunction,
const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling,
- bool grayscale, ScreenCaptureResults&) EXCLUDES(mStateLock)
+ bool grayscale, bool isProtected, ScreenCaptureResults&) EXCLUDES(mStateLock)
REQUIRES(kMainThreadContext);
// If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index 07a606c..2d74828 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -124,6 +124,7 @@
DUMP_READ_ONLY_FLAG(use_known_refresh_rate_for_fps_consistency);
DUMP_READ_ONLY_FLAG(cache_if_source_crop_layer_only_moved);
DUMP_READ_ONLY_FLAG(enable_fro_dependent_features);
+ DUMP_READ_ONLY_FLAG(display_protected);
#undef DUMP_READ_ONLY_FLAG
#undef DUMP_SERVER_FLAG
@@ -197,6 +198,7 @@
FLAG_MANAGER_READ_ONLY_FLAG(cache_if_source_crop_layer_only_moved,
"debug.sf.cache_source_crop_only_moved")
FLAG_MANAGER_READ_ONLY_FLAG(enable_fro_dependent_features, "")
+FLAG_MANAGER_READ_ONLY_FLAG(display_protected, "")
/// Trunk stable server flags ///
FLAG_MANAGER_SERVER_FLAG(late_boot_misc2, "")
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
index 38cb43a..e0f6204 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -63,6 +63,7 @@
bool use_known_refresh_rate_for_fps_consistency() const;
bool cache_if_source_crop_layer_only_moved() const;
bool enable_fro_dependent_features() const;
+ bool display_protected() const;
protected:
// overridden for unit tests
diff --git a/services/surfaceflinger/surfaceflinger_flags.aconfig b/services/surfaceflinger/surfaceflinger_flags.aconfig
index fcb52c7..620ac26 100644
--- a/services/surfaceflinger/surfaceflinger_flags.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags.aconfig
@@ -107,3 +107,11 @@
bug: "314217419"
is_fixed_read_only: true
}
+
+flag {
+ name: "display_protected"
+ namespace: "core_graphics"
+ description: "Introduce protected displays to specify whether they should render protected content"
+ bug: "301647974"
+ is_fixed_read_only: true
+}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index ebb05d4..8ba6bf8 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -498,7 +498,8 @@
return FTL_FAKE_GUARD(kMainThreadContext,
mFlinger->renderScreenImpl(std::move(renderArea), traverseLayers,
buffer, regionSampling,
- false /* grayscale */, captureResults));
+ false /* grayscale */,
+ false /* isProtected */, captureResults));
}
auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid,