From f6fb445b73f0c84f92f74c799effac08e18c4c1c Mon Sep 17 00:00:00 2001 From: Chavi Weingarten Date: Tue, 23 Jan 2024 21:10:30 +0000 Subject: Add captureLayersSync function This captureLayers function in SurfaceFlinger will wait on the requested binder thread for the screenshot composition to complete before returning the buffer to the client. This is different than the existing captureLayers method since the other request is oneway and invokes the screen capture callback on a different binder thread. This is needed because there are places in system server that request screenshots while holding a lock and then wait synchronously on the results. While waiting on the buffer and holding the lock, additional two way binder calls can be made into system server that are waiting to acquire the same lock. If there are enough requests, we may run out of binder threads and then the screen capture result can't be posted back to system server because it needs a free binder thread. This will result in a deadlock because the lock that the screenshot request is holding can never be unlocked without a free binder thread. Binder threads will never be freed up because they are waiting to acquire the lock. The async screencapture code is still useful for cases where there's no global lock being held while waiting on results or the results is posted to another thread. Test: Screenshots Bug: 321263247 Change-Id: I259173a59f488995e13af8f7dd2ca98c3bbf8639 --- services/surfaceflinger/SurfaceFlinger.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'services/surfaceflinger/SurfaceFlinger.cpp') diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index fe5b159051..178828a5f6 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -116,6 +116,7 @@ #include #include #include +#include #include #include "BackgroundExecutor.h" #include "Client.h" @@ -7842,6 +7843,12 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args kAllowProtected, kGrayscale, captureListener); } +ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& args) { + sp captureListener = sp::make(); + captureLayers(args, captureListener); + return captureListener->waitForResults(); +} + void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, const sp& captureListener) { ATRACE_CALL(); @@ -9686,6 +9693,12 @@ binder::Status SurfaceComposerAIDL::captureDisplayById( return binderStatusFromStatusT(NO_ERROR); } +binder::Status SurfaceComposerAIDL::captureLayersSync(const LayerCaptureArgs& args, + ScreenCaptureResults* outResults) { + *outResults = mFlinger->captureLayersSync(args); + return binderStatusFromStatusT(NO_ERROR); +} + binder::Status SurfaceComposerAIDL::captureLayers( const LayerCaptureArgs& args, const sp& captureListener) { mFlinger->captureLayers(args, captureListener); -- cgit v1.2.3-59-g8ed1b