Loading libs/gui/aidl/android/gui/ISurfaceComposer.aidl +3 −3 Original line number Original line Diff line number Diff line Loading @@ -230,20 +230,20 @@ interface ISurfaceComposer { * The subregion can be optionally rotated. It will also be scaled to * The subregion can be optionally rotated. It will also be scaled to * match the size of the output buffer. * match the size of the output buffer. */ */ void captureDisplay(in DisplayCaptureArgs args, IScreenCaptureListener listener); oneway void captureDisplay(in DisplayCaptureArgs args, IScreenCaptureListener listener); /** /** * Capture the specified screen. This requires the READ_FRAME_BUFFER * Capture the specified screen. This requires the READ_FRAME_BUFFER * permission. * permission. */ */ void captureDisplayById(long displayId, IScreenCaptureListener listener); oneway void captureDisplayById(long displayId, IScreenCaptureListener listener); /** /** * Capture a subtree of the layer hierarchy, potentially ignoring the root node. * Capture a subtree of the layer hierarchy, potentially ignoring the root node. * This requires READ_FRAME_BUFFER permission. This function will fail if there * This requires READ_FRAME_BUFFER permission. This function will fail if there * is a secure window on screen * is a secure window on screen */ */ void captureLayers(in LayerCaptureArgs args, IScreenCaptureListener listener); oneway void captureLayers(in LayerCaptureArgs args, IScreenCaptureListener listener); /** /** * Clears the frame statistics for animations. * Clears the frame statistics for animations. Loading services/surfaceflinger/SurfaceFlinger.cpp +69 −47 Original line number Original line Diff line number Diff line Loading @@ -7332,16 +7332,27 @@ ui::Dataspace pickBestDataspace(ui::Dataspace requestedDataspace, const DisplayD } // namespace } // namespace status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, static void invokeScreenCaptureError(const status_t status, const sp<IScreenCaptureListener>& captureListener) { ScreenCaptureResults captureResults; captureResults.fenceResult = base::unexpected(status); captureListener->onScreenCaptureCompleted(captureResults); } void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); ATRACE_CALL(); status_t validate = validateScreenshotPermissions(args); status_t validate = validateScreenshotPermissions(args); if (validate != OK) { if (validate != OK) { return validate; invokeScreenCaptureError(validate, captureListener); return; } } if (!args.displayToken) return BAD_VALUE; if (!args.displayToken) { invokeScreenCaptureError(BAD_VALUE, captureListener); return; } wp<const DisplayDevice> displayWeak; wp<const DisplayDevice> displayWeak; ui::LayerStack layerStack; ui::LayerStack layerStack; Loading @@ -7350,7 +7361,10 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, { { Mutex::Autolock lock(mStateLock); Mutex::Autolock lock(mStateLock); sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken); sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken); if (!display) return NAME_NOT_FOUND; if (!display) { invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } displayWeak = display; displayWeak = display; layerStack = display->getLayerStack(); layerStack = display->getLayerStack(); Loading @@ -7365,7 +7379,8 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, excludeLayerIds.emplace(excludeLayer); excludeLayerIds.emplace(excludeLayer); } else { } else { ALOGW("Invalid layer handle passed as excludeLayer to captureDisplay"); ALOGW("Invalid layer handle passed as excludeLayer to captureDisplay"); return NAME_NOT_FOUND; invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } } } } } } Loading @@ -7388,13 +7403,11 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers); getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers); } } auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, args.pixelFormat, args.pixelFormat, args.allowProtected, args.grayscale, args.allowProtected, args.grayscale, captureListener); captureListener); return fenceStatus(future.get()); } } status_t SurfaceFlinger::captureDisplay(DisplayId displayId, void SurfaceFlinger::captureDisplay(DisplayId displayId, const sp<IScreenCaptureListener>& captureListener) { const sp<IScreenCaptureListener>& captureListener) { ui::LayerStack layerStack; ui::LayerStack layerStack; wp<const DisplayDevice> displayWeak; wp<const DisplayDevice> displayWeak; Loading @@ -7404,7 +7417,8 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId, const auto display = getDisplayDeviceLocked(displayId); const auto display = getDisplayDeviceLocked(displayId); if (!display) { if (!display) { return NAME_NOT_FOUND; invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } } displayWeak = display; displayWeak = display; Loading Loading @@ -7432,25 +7446,25 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId, if (captureListener == nullptr) { if (captureListener == nullptr) { ALOGE("capture screen must provide a capture listener callback"); ALOGE("capture screen must provide a capture listener callback"); return BAD_VALUE; invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } constexpr bool kAllowProtected = false; constexpr bool kAllowProtected = false; constexpr bool kGrayscale = false; constexpr bool kGrayscale = false; auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, size, captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, size, ui::PixelFormat::RGBA_8888, kAllowProtected, kGrayscale, ui::PixelFormat::RGBA_8888, kAllowProtected, kGrayscale, captureListener); captureListener); return fenceStatus(future.get()); } } status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); ATRACE_CALL(); status_t validate = validateScreenshotPermissions(args); status_t validate = validateScreenshotPermissions(args); if (validate != OK) { if (validate != OK) { return validate; invokeScreenCaptureError(validate, captureListener); return; } } ui::Size reqSize; ui::Size reqSize; Loading @@ -7468,13 +7482,15 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, parent = LayerHandle::getLayer(args.layerHandle); parent = LayerHandle::getLayer(args.layerHandle); if (parent == nullptr) { if (parent == nullptr) { ALOGE("captureLayers called with an invalid or removed parent"); ALOGE("captureLayers called with an invalid or removed parent"); return NAME_NOT_FOUND; invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } } if (!canCaptureBlackoutContent && if (!canCaptureBlackoutContent && parent->getDrawingState().flags & layer_state_t::eLayerSecure) { parent->getDrawingState().flags & layer_state_t::eLayerSecure) { ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); return PERMISSION_DENIED; invokeScreenCaptureError(PERMISSION_DENIED, captureListener); return; } } Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState()); Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState()); Loading @@ -7491,7 +7507,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, if (crop.isEmpty() || args.frameScaleX <= 0.0f || args.frameScaleY <= 0.0f) { if (crop.isEmpty() || args.frameScaleX <= 0.0f || args.frameScaleY <= 0.0f) { // Error out if the layer has no source bounds (i.e. they are boundless) and a source // Error out if the layer has no source bounds (i.e. they are boundless) and a source // crop was not specified, or an invalid frame scale was provided. // crop was not specified, or an invalid frame scale was provided. return BAD_VALUE; invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY); reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY); Loading @@ -7501,7 +7518,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, excludeLayerIds.emplace(excludeLayer); excludeLayerIds.emplace(excludeLayer); } else { } else { ALOGW("Invalid layer handle passed as excludeLayer to captureLayers"); ALOGW("Invalid layer handle passed as excludeLayer to captureLayers"); return NAME_NOT_FOUND; invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } } } } } // mStateLock } // mStateLock Loading @@ -7509,7 +7527,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, // really small crop or frameScale // really small crop or frameScale if (reqSize.width <= 0 || reqSize.height <= 0) { if (reqSize.width <= 0 || reqSize.height <= 0) { ALOGW("Failed to captureLayes: crop or scale too small"); ALOGW("Failed to captureLayes: crop or scale too small"); return BAD_VALUE; invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } bool childrenOnly = args.childrenOnly; bool childrenOnly = args.childrenOnly; Loading Loading @@ -7573,18 +7592,18 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, if (captureListener == nullptr) { if (captureListener == nullptr) { ALOGE("capture screen must provide a capture listener callback"); ALOGE("capture screen must provide a capture listener callback"); return BAD_VALUE; invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, args.pixelFormat, args.pixelFormat, args.allowProtected, args.grayscale, args.allowProtected, args.grayscale, captureListener); captureListener); return fenceStatus(future.get()); } } ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, RenderAreaFuture renderAreaFuture, GetLayerSnapshotsFunction getLayerSnapshots, GetLayerSnapshotsFunction getLayerSnapshots, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool grayscale, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool grayscale, const sp<IScreenCaptureListener>& captureListener) { const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); ATRACE_CALL(); Loading @@ -7592,7 +7611,8 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32 ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32 ") that exceeds render target size limit.", ") that exceeds render target size limit.", bufferSize.getWidth(), bufferSize.getHeight()); bufferSize.getWidth(), bufferSize.getHeight()); return ftl::yield<FenceResult>(base::unexpected(BAD_VALUE)).share(); invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } // Loop over all visible layers to see whether there's any protected layer. A protected layer is // Loop over all visible layers to see whether there's any protected layer. A protected layer is Loading Loading @@ -7632,14 +7652,16 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( // Otherwise an irreponsible process may cause an SF crash by allocating // Otherwise an irreponsible process may cause an SF crash by allocating // too much. // too much. ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus); ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus); return ftl::yield<FenceResult>(base::unexpected(bufferStatus)).share(); invokeScreenCaptureError(bufferStatus, captureListener); return; } } const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared< const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared< renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), renderengine::impl::ExternalTexture::Usage:: renderengine::impl::ExternalTexture::Usage:: WRITEABLE); WRITEABLE); return captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, texture, auto fence = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, texture, false /* regionSampling */, grayscale, captureListener); false /* regionSampling */, grayscale, captureListener); fence.get(); } } ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( Loading Loading @@ -9079,28 +9101,28 @@ binder::Status SurfaceComposerAIDL::setGameContentType(const sp<IBinder>& displa binder::Status SurfaceComposerAIDL::captureDisplay( binder::Status SurfaceComposerAIDL::captureDisplay( const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { status_t status = mFlinger->captureDisplay(args, captureListener); mFlinger->captureDisplay(args, captureListener); return binderStatusFromStatusT(status); return binderStatusFromStatusT(NO_ERROR); } } binder::Status SurfaceComposerAIDL::captureDisplayById( binder::Status SurfaceComposerAIDL::captureDisplayById( int64_t displayId, const sp<IScreenCaptureListener>& captureListener) { int64_t displayId, const sp<IScreenCaptureListener>& captureListener) { status_t status; // status_t status; IPCThreadState* ipc = IPCThreadState::self(); IPCThreadState* ipc = IPCThreadState::self(); const int uid = ipc->getCallingUid(); const int uid = ipc->getCallingUid(); if (uid == AID_ROOT || uid == AID_GRAPHICS || uid == AID_SYSTEM || uid == AID_SHELL) { if (uid == AID_ROOT || uid == AID_GRAPHICS || uid == AID_SYSTEM || uid == AID_SHELL) { std::optional<DisplayId> id = DisplayId::fromValue(static_cast<uint64_t>(displayId)); std::optional<DisplayId> id = DisplayId::fromValue(static_cast<uint64_t>(displayId)); status = mFlinger->captureDisplay(*id, captureListener); mFlinger->captureDisplay(*id, captureListener); } else { } else { status = PERMISSION_DENIED; invokeScreenCaptureError(PERMISSION_DENIED, captureListener); } } return binderStatusFromStatusT(status); return binderStatusFromStatusT(NO_ERROR); } } binder::Status SurfaceComposerAIDL::captureLayers( binder::Status SurfaceComposerAIDL::captureLayers( const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { status_t status = mFlinger->captureLayers(args, captureListener); mFlinger->captureLayers(args, captureListener); return binderStatusFromStatusT(status); return binderStatusFromStatusT(NO_ERROR); } } binder::Status SurfaceComposerAIDL::overrideHdrTypes(const sp<IBinder>& display, binder::Status SurfaceComposerAIDL::overrideHdrTypes(const sp<IBinder>& display, Loading services/surfaceflinger/SurfaceFlinger.h +6 −7 Original line number Original line Diff line number Diff line Loading @@ -535,9 +535,9 @@ private: EventRegistrationFlags eventRegistration = {}, EventRegistrationFlags eventRegistration = {}, const sp<IBinder>& layerHandle = nullptr); const sp<IBinder>& layerHandle = nullptr); status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&); void captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&); status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&); void captureDisplay(DisplayId, const sp<IScreenCaptureListener>&); status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&); void captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&); status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats); status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats); status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*) status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*) Loading Loading @@ -836,9 +836,8 @@ private: // Boot animation, on/off animations and screen capture // Boot animation, on/off animations and screen capture void startBootAnim(); void startBootAnim(); ftl::SharedFuture<FenceResult> captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, void captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, ui::Size bufferSize, ui::Size bufferSize, ui::PixelFormat, ui::PixelFormat, bool allowProtected, bool grayscale, bool allowProtected, bool grayscale, const sp<IScreenCaptureListener>&); const sp<IScreenCaptureListener>&); ftl::SharedFuture<FenceResult> captureScreenCommon( ftl::SharedFuture<FenceResult> captureScreenCommon( RenderAreaFuture, GetLayerSnapshotsFunction, RenderAreaFuture, GetLayerSnapshotsFunction, Loading Loading
libs/gui/aidl/android/gui/ISurfaceComposer.aidl +3 −3 Original line number Original line Diff line number Diff line Loading @@ -230,20 +230,20 @@ interface ISurfaceComposer { * The subregion can be optionally rotated. It will also be scaled to * The subregion can be optionally rotated. It will also be scaled to * match the size of the output buffer. * match the size of the output buffer. */ */ void captureDisplay(in DisplayCaptureArgs args, IScreenCaptureListener listener); oneway void captureDisplay(in DisplayCaptureArgs args, IScreenCaptureListener listener); /** /** * Capture the specified screen. This requires the READ_FRAME_BUFFER * Capture the specified screen. This requires the READ_FRAME_BUFFER * permission. * permission. */ */ void captureDisplayById(long displayId, IScreenCaptureListener listener); oneway void captureDisplayById(long displayId, IScreenCaptureListener listener); /** /** * Capture a subtree of the layer hierarchy, potentially ignoring the root node. * Capture a subtree of the layer hierarchy, potentially ignoring the root node. * This requires READ_FRAME_BUFFER permission. This function will fail if there * This requires READ_FRAME_BUFFER permission. This function will fail if there * is a secure window on screen * is a secure window on screen */ */ void captureLayers(in LayerCaptureArgs args, IScreenCaptureListener listener); oneway void captureLayers(in LayerCaptureArgs args, IScreenCaptureListener listener); /** /** * Clears the frame statistics for animations. * Clears the frame statistics for animations. Loading
services/surfaceflinger/SurfaceFlinger.cpp +69 −47 Original line number Original line Diff line number Diff line Loading @@ -7332,16 +7332,27 @@ ui::Dataspace pickBestDataspace(ui::Dataspace requestedDataspace, const DisplayD } // namespace } // namespace status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, static void invokeScreenCaptureError(const status_t status, const sp<IScreenCaptureListener>& captureListener) { ScreenCaptureResults captureResults; captureResults.fenceResult = base::unexpected(status); captureListener->onScreenCaptureCompleted(captureResults); } void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); ATRACE_CALL(); status_t validate = validateScreenshotPermissions(args); status_t validate = validateScreenshotPermissions(args); if (validate != OK) { if (validate != OK) { return validate; invokeScreenCaptureError(validate, captureListener); return; } } if (!args.displayToken) return BAD_VALUE; if (!args.displayToken) { invokeScreenCaptureError(BAD_VALUE, captureListener); return; } wp<const DisplayDevice> displayWeak; wp<const DisplayDevice> displayWeak; ui::LayerStack layerStack; ui::LayerStack layerStack; Loading @@ -7350,7 +7361,10 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, { { Mutex::Autolock lock(mStateLock); Mutex::Autolock lock(mStateLock); sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken); sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken); if (!display) return NAME_NOT_FOUND; if (!display) { invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } displayWeak = display; displayWeak = display; layerStack = display->getLayerStack(); layerStack = display->getLayerStack(); Loading @@ -7365,7 +7379,8 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, excludeLayerIds.emplace(excludeLayer); excludeLayerIds.emplace(excludeLayer); } else { } else { ALOGW("Invalid layer handle passed as excludeLayer to captureDisplay"); ALOGW("Invalid layer handle passed as excludeLayer to captureDisplay"); return NAME_NOT_FOUND; invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } } } } } } Loading @@ -7388,13 +7403,11 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers); getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers); } } auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, args.pixelFormat, args.pixelFormat, args.allowProtected, args.grayscale, args.allowProtected, args.grayscale, captureListener); captureListener); return fenceStatus(future.get()); } } status_t SurfaceFlinger::captureDisplay(DisplayId displayId, void SurfaceFlinger::captureDisplay(DisplayId displayId, const sp<IScreenCaptureListener>& captureListener) { const sp<IScreenCaptureListener>& captureListener) { ui::LayerStack layerStack; ui::LayerStack layerStack; wp<const DisplayDevice> displayWeak; wp<const DisplayDevice> displayWeak; Loading @@ -7404,7 +7417,8 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId, const auto display = getDisplayDeviceLocked(displayId); const auto display = getDisplayDeviceLocked(displayId); if (!display) { if (!display) { return NAME_NOT_FOUND; invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } } displayWeak = display; displayWeak = display; Loading Loading @@ -7432,25 +7446,25 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId, if (captureListener == nullptr) { if (captureListener == nullptr) { ALOGE("capture screen must provide a capture listener callback"); ALOGE("capture screen must provide a capture listener callback"); return BAD_VALUE; invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } constexpr bool kAllowProtected = false; constexpr bool kAllowProtected = false; constexpr bool kGrayscale = false; constexpr bool kGrayscale = false; auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, size, captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, size, ui::PixelFormat::RGBA_8888, kAllowProtected, kGrayscale, ui::PixelFormat::RGBA_8888, kAllowProtected, kGrayscale, captureListener); captureListener); return fenceStatus(future.get()); } } status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); ATRACE_CALL(); status_t validate = validateScreenshotPermissions(args); status_t validate = validateScreenshotPermissions(args); if (validate != OK) { if (validate != OK) { return validate; invokeScreenCaptureError(validate, captureListener); return; } } ui::Size reqSize; ui::Size reqSize; Loading @@ -7468,13 +7482,15 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, parent = LayerHandle::getLayer(args.layerHandle); parent = LayerHandle::getLayer(args.layerHandle); if (parent == nullptr) { if (parent == nullptr) { ALOGE("captureLayers called with an invalid or removed parent"); ALOGE("captureLayers called with an invalid or removed parent"); return NAME_NOT_FOUND; invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } } if (!canCaptureBlackoutContent && if (!canCaptureBlackoutContent && parent->getDrawingState().flags & layer_state_t::eLayerSecure) { parent->getDrawingState().flags & layer_state_t::eLayerSecure) { ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); return PERMISSION_DENIED; invokeScreenCaptureError(PERMISSION_DENIED, captureListener); return; } } Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState()); Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState()); Loading @@ -7491,7 +7507,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, if (crop.isEmpty() || args.frameScaleX <= 0.0f || args.frameScaleY <= 0.0f) { if (crop.isEmpty() || args.frameScaleX <= 0.0f || args.frameScaleY <= 0.0f) { // Error out if the layer has no source bounds (i.e. they are boundless) and a source // Error out if the layer has no source bounds (i.e. they are boundless) and a source // crop was not specified, or an invalid frame scale was provided. // crop was not specified, or an invalid frame scale was provided. return BAD_VALUE; invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY); reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY); Loading @@ -7501,7 +7518,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, excludeLayerIds.emplace(excludeLayer); excludeLayerIds.emplace(excludeLayer); } else { } else { ALOGW("Invalid layer handle passed as excludeLayer to captureLayers"); ALOGW("Invalid layer handle passed as excludeLayer to captureLayers"); return NAME_NOT_FOUND; invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); return; } } } } } // mStateLock } // mStateLock Loading @@ -7509,7 +7527,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, // really small crop or frameScale // really small crop or frameScale if (reqSize.width <= 0 || reqSize.height <= 0) { if (reqSize.width <= 0 || reqSize.height <= 0) { ALOGW("Failed to captureLayes: crop or scale too small"); ALOGW("Failed to captureLayes: crop or scale too small"); return BAD_VALUE; invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } bool childrenOnly = args.childrenOnly; bool childrenOnly = args.childrenOnly; Loading Loading @@ -7573,18 +7592,18 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, if (captureListener == nullptr) { if (captureListener == nullptr) { ALOGE("capture screen must provide a capture listener callback"); ALOGE("capture screen must provide a capture listener callback"); return BAD_VALUE; invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, args.pixelFormat, args.pixelFormat, args.allowProtected, args.grayscale, args.allowProtected, args.grayscale, captureListener); captureListener); return fenceStatus(future.get()); } } ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, RenderAreaFuture renderAreaFuture, GetLayerSnapshotsFunction getLayerSnapshots, GetLayerSnapshotsFunction getLayerSnapshots, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool grayscale, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool grayscale, const sp<IScreenCaptureListener>& captureListener) { const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); ATRACE_CALL(); Loading @@ -7592,7 +7611,8 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32 ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32 ") that exceeds render target size limit.", ") that exceeds render target size limit.", bufferSize.getWidth(), bufferSize.getHeight()); bufferSize.getWidth(), bufferSize.getHeight()); return ftl::yield<FenceResult>(base::unexpected(BAD_VALUE)).share(); invokeScreenCaptureError(BAD_VALUE, captureListener); return; } } // Loop over all visible layers to see whether there's any protected layer. A protected layer is // Loop over all visible layers to see whether there's any protected layer. A protected layer is Loading Loading @@ -7632,14 +7652,16 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( // Otherwise an irreponsible process may cause an SF crash by allocating // Otherwise an irreponsible process may cause an SF crash by allocating // too much. // too much. ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus); ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus); return ftl::yield<FenceResult>(base::unexpected(bufferStatus)).share(); invokeScreenCaptureError(bufferStatus, captureListener); return; } } const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared< const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared< renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), renderengine::impl::ExternalTexture::Usage:: renderengine::impl::ExternalTexture::Usage:: WRITEABLE); WRITEABLE); return captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, texture, auto fence = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, texture, false /* regionSampling */, grayscale, captureListener); false /* regionSampling */, grayscale, captureListener); fence.get(); } } ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( Loading Loading @@ -9079,28 +9101,28 @@ binder::Status SurfaceComposerAIDL::setGameContentType(const sp<IBinder>& displa binder::Status SurfaceComposerAIDL::captureDisplay( binder::Status SurfaceComposerAIDL::captureDisplay( const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { status_t status = mFlinger->captureDisplay(args, captureListener); mFlinger->captureDisplay(args, captureListener); return binderStatusFromStatusT(status); return binderStatusFromStatusT(NO_ERROR); } } binder::Status SurfaceComposerAIDL::captureDisplayById( binder::Status SurfaceComposerAIDL::captureDisplayById( int64_t displayId, const sp<IScreenCaptureListener>& captureListener) { int64_t displayId, const sp<IScreenCaptureListener>& captureListener) { status_t status; // status_t status; IPCThreadState* ipc = IPCThreadState::self(); IPCThreadState* ipc = IPCThreadState::self(); const int uid = ipc->getCallingUid(); const int uid = ipc->getCallingUid(); if (uid == AID_ROOT || uid == AID_GRAPHICS || uid == AID_SYSTEM || uid == AID_SHELL) { if (uid == AID_ROOT || uid == AID_GRAPHICS || uid == AID_SYSTEM || uid == AID_SHELL) { std::optional<DisplayId> id = DisplayId::fromValue(static_cast<uint64_t>(displayId)); std::optional<DisplayId> id = DisplayId::fromValue(static_cast<uint64_t>(displayId)); status = mFlinger->captureDisplay(*id, captureListener); mFlinger->captureDisplay(*id, captureListener); } else { } else { status = PERMISSION_DENIED; invokeScreenCaptureError(PERMISSION_DENIED, captureListener); } } return binderStatusFromStatusT(status); return binderStatusFromStatusT(NO_ERROR); } } binder::Status SurfaceComposerAIDL::captureLayers( binder::Status SurfaceComposerAIDL::captureLayers( const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { status_t status = mFlinger->captureLayers(args, captureListener); mFlinger->captureLayers(args, captureListener); return binderStatusFromStatusT(status); return binderStatusFromStatusT(NO_ERROR); } } binder::Status SurfaceComposerAIDL::overrideHdrTypes(const sp<IBinder>& display, binder::Status SurfaceComposerAIDL::overrideHdrTypes(const sp<IBinder>& display, Loading
services/surfaceflinger/SurfaceFlinger.h +6 −7 Original line number Original line Diff line number Diff line Loading @@ -535,9 +535,9 @@ private: EventRegistrationFlags eventRegistration = {}, EventRegistrationFlags eventRegistration = {}, const sp<IBinder>& layerHandle = nullptr); const sp<IBinder>& layerHandle = nullptr); status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&); void captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&); status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&); void captureDisplay(DisplayId, const sp<IScreenCaptureListener>&); status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&); void captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&); status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats); status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats); status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*) status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*) Loading Loading @@ -836,9 +836,8 @@ private: // Boot animation, on/off animations and screen capture // Boot animation, on/off animations and screen capture void startBootAnim(); void startBootAnim(); ftl::SharedFuture<FenceResult> captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, void captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, ui::Size bufferSize, ui::Size bufferSize, ui::PixelFormat, ui::PixelFormat, bool allowProtected, bool grayscale, bool allowProtected, bool grayscale, const sp<IScreenCaptureListener>&); const sp<IScreenCaptureListener>&); ftl::SharedFuture<FenceResult> captureScreenCommon( ftl::SharedFuture<FenceResult> captureScreenCommon( RenderAreaFuture, GetLayerSnapshotsFunction, RenderAreaFuture, GetLayerSnapshotsFunction, Loading