From 93df2ea991d6f9c5c64280ac9947e44653d61fbf Mon Sep 17 00:00:00 2001 From: chaviw Date: Tue, 30 Apr 2019 16:45:12 -0700 Subject: Added captureScreen function for displayId or layerStack Previously, screencap shell command could accept a display id as an argument. It would use the id to look up information about the display (displayToken, orientation, colorMode) by making requests into SurfaceFlinger. Since those requests only worked for physical display ids, screencap didn't work to capture virtual displays. Instead of adding new methods to look up display information for a virtual display, this change just adds a new captureScreen function in SurfaceFlinger that accepts a displayId or layerStack and handles getting the default info for the requested display. This works for both physical and virtual displays. Test: adb shell screencap -d Fixes: 130974213 Change-Id: I24b7558c973a057414c6b4f81ab1d60152fff38d --- libs/gui/ISurfaceComposer.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'libs/gui/ISurfaceComposer.cpp') diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index a8b1a4c7af..4372e16a1f 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -142,6 +142,28 @@ public: return result; } + virtual status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace, + sp* outBuffer) { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + data.writeUint64(displayOrLayerStack); + status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_BY_ID, data, &reply); + if (result != NO_ERROR) { + ALOGE("captureScreen failed to transact: %d", result); + return result; + } + result = reply.readInt32(); + if (result != NO_ERROR) { + ALOGE("captureScreen failed to readInt32: %d", result); + return result; + } + + *outDataspace = static_cast(reply.readInt32()); + *outBuffer = new GraphicBuffer(); + reply.read(**outBuffer); + return result; + } + virtual status_t captureLayers( const sp& layerHandleBinder, sp* outBuffer, const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, @@ -1042,6 +1064,19 @@ status_t BnSurfaceComposer::onTransact( } return NO_ERROR; } + case CAPTURE_SCREEN_BY_ID: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + uint64_t displayOrLayerStack = data.readUint64(); + ui::Dataspace outDataspace = ui::Dataspace::V0_SRGB; + sp outBuffer; + status_t res = captureScreen(displayOrLayerStack, &outDataspace, &outBuffer); + reply->writeInt32(res); + if (res == NO_ERROR) { + reply->writeInt32(static_cast(outDataspace)); + reply->write(*outBuffer); + } + return NO_ERROR; + } case CAPTURE_LAYERS: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp layerHandleBinder = data.readStrongBinder(); -- cgit v1.2.3-59-g8ed1b