diff options
18 files changed, 86 insertions, 30 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h index 98c4af487e..6e60839dd9 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h @@ -42,6 +42,10 @@ struct DisplayCreationArgs { // 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 @@ public: 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 ccff1eccb6..a1d61323a8 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h @@ -97,7 +97,7 @@ public: 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 @@ using LayerFESet = std::unordered_set<sp<LayerFE>, LayerFESpHash>; 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 @@ static inline void PrintTo(const LayerFE::ClientCompositionTargetSettings& setti 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 692ed24899..6b1c318d1c 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h @@ -53,6 +53,9 @@ struct OutputCompositionState { // 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 0475881bae..690d35f068 100644 --- a/services/surfaceflinger/CompositionEngine/src/Display.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp @@ -57,6 +57,7 @@ void Display::setConfiguration(const compositionengine::DisplayCreationArgs& arg 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 e4d757810a..c399224491 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -1232,10 +1232,18 @@ void Output::updateProtectedContentState() { 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 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( 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 579c6ba772..869dda61bb 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp @@ -184,7 +184,7 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te 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 249c40b473..950b05e1da 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -72,6 +72,7 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) 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 51c7be0490..ac390cb8ff 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -332,6 +332,7 @@ struct DisplayDeviceState { 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 @@ struct DisplayDeviceCreationArgs { 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 f25619a6c0..2dbcb841ac 100644 --- a/services/surfaceflinger/LayerFE.cpp +++ b/services/surfaceflinger/LayerFE.cpp @@ -208,9 +208,15 @@ void LayerFE::prepareBufferStateClientComposition( // 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 6db39f143f..c888ccc8ae 100644 --- a/services/surfaceflinger/RegionSamplingThread.cpp +++ b/services/surfaceflinger/RegionSamplingThread.cpp @@ -374,10 +374,11 @@ void RegionSamplingThread::captureSample() { 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 57b0d5e0ea..a4a5ce2b46 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.cpp +++ b/services/surfaceflinger/ScreenCaptureOutput.cpp @@ -32,6 +32,7 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp 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 fc095def99..1c16308e15 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.h +++ b/services/surfaceflinger/ScreenCaptureOutput.h @@ -38,6 +38,7 @@ struct ScreenCaptureOutputArgs { 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 1dcc19e40d..c4de02fce9 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -565,6 +565,9 @@ sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, bool secur // 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 @@ const char* SurfaceFlinger::processHotplug(PhysicalDisplayId displayId, .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 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( 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 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, 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 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, }) .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 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, 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> SurfaceFlinger::captureScreenCommon( 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::captureScreenCommon( 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 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( }; 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 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( .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 c4af271742..6909055801 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -855,11 +855,11 @@ private: 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 07a606c9ed..2d7482862a 100644 --- a/services/surfaceflinger/common/FlagManager.cpp +++ b/services/surfaceflinger/common/FlagManager.cpp @@ -124,6 +124,7 @@ void FlagManager::dump(std::string& result) const { 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(use_known_refresh_rate_for_fps_consistency, "") 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 38cb43a269..e0f620465c 100644 --- a/services/surfaceflinger/common/include/common/FlagManager.h +++ b/services/surfaceflinger/common/include/common/FlagManager.h @@ -63,6 +63,7 @@ public: 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 fcb52c72f4..620ac26cfd 100644 --- a/services/surfaceflinger/surfaceflinger_flags.aconfig +++ b/services/surfaceflinger/surfaceflinger_flags.aconfig @@ -107,3 +107,11 @@ flag { 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 ebb05d4da7..8ba6bf87e2 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -498,7 +498,8 @@ public: 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, |