diff options
author | 2020-07-24 17:42:39 -0700 | |
---|---|---|
committer | 2020-07-30 16:53:13 -0700 | |
commit | d24328904823a47edc328d2dceb167f73f74850b (patch) | |
tree | 09bb583e20485187620517a7666a24c71697dbab | |
parent | 6278ece89a4745141d9fc83d2affffa40614db22 (diff) |
Use DisplayCaptureArgs for displayCapture functions.
Updated displayCapture functions to use the DisplayCaptureArgs and
ScreenCaptureResults instead of the list of arguments and out arguments.
This only updated the native code, not JNI or Java
Test: display screenshot + secure works
Test: adb shell screencap
Test: SurfaceFlinger_test
Bug: 162367424
Change-Id: I5210a0881c96436c128c3ffb328a5a6ee01beca7
-rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 90 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 26 | ||||
-rw-r--r-- | libs/gui/include/gui/ISurfaceComposer.h | 67 | ||||
-rw-r--r-- | libs/gui/tests/BLASTBufferQueue_test.cpp | 50 | ||||
-rw-r--r-- | libs/gui/tests/Surface_test.cpp | 28 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 81 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 11 | ||||
-rw-r--r-- | services/surfaceflinger/tests/LayerTransactionTest.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/tests/LayerTransaction_test.cpp | 19 | ||||
-rw-r--r-- | services/surfaceflinger/tests/LayerTypeTransaction_test.cpp | 10 | ||||
-rw-r--r-- | services/surfaceflinger/tests/utils/ScreenshotUtils.h | 9 |
11 files changed, 170 insertions, 226 deletions
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 6881be3e77..7b9b5d8d88 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -111,59 +111,49 @@ public: remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); } - virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer, - bool& outCapturedSecureLayers, ui::Dataspace reqDataspace, - ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, - uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - ui::Rotation rotation, bool captureSecureLayers) { + virtual status_t captureDisplay(const DisplayCaptureArgs& args, + ScreenCaptureResults& captureResults) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); - data.writeStrongBinder(display); - data.writeInt32(static_cast<int32_t>(reqDataspace)); - data.writeInt32(static_cast<int32_t>(reqPixelFormat)); - data.write(sourceCrop); - data.writeUint32(reqWidth); - data.writeUint32(reqHeight); - data.writeInt32(static_cast<int32_t>(useIdentityTransform)); - data.writeInt32(static_cast<int32_t>(rotation)); - data.writeInt32(static_cast<int32_t>(captureSecureLayers)); - status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); + + status_t result = args.write(data); if (result != NO_ERROR) { - ALOGE("captureScreen failed to transact: %d", result); + ALOGE("captureDisplay failed to parcel args: %d", result); + return result; + } + result = remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY, data, &reply); + if (result != NO_ERROR) { + ALOGE("captureDisplay failed to transact: %d", result); return result; } result = reply.readInt32(); if (result != NO_ERROR) { - ALOGE("captureScreen failed to readInt32: %d", result); + ALOGE("captureDisplay failed to readInt32: %d", result); return result; } - *outBuffer = new GraphicBuffer(); - reply.read(**outBuffer); - outCapturedSecureLayers = reply.readBool(); - + captureResults.read(reply); return result; } - virtual status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace, - sp<GraphicBuffer>* outBuffer) { + virtual status_t captureDisplay(uint64_t displayOrLayerStack, + ScreenCaptureResults& captureResults) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeUint64(displayOrLayerStack); - status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_BY_ID, data, &reply); + status_t result = + remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID, data, &reply); if (result != NO_ERROR) { - ALOGE("captureScreen failed to transact: %d", result); + ALOGE("captureDisplay failed to transact: %d", result); return result; } result = reply.readInt32(); if (result != NO_ERROR) { - ALOGE("captureScreen failed to readInt32: %d", result); + ALOGE("captureDisplay failed to readInt32: %d", result); return result; } - *outDataspace = static_cast<ui::Dataspace>(reply.readInt32()); - *outBuffer = new GraphicBuffer(); - reply.read(**outBuffer); + captureResults.read(reply); return result; } @@ -1293,43 +1283,33 @@ status_t BnSurfaceComposer::onTransact( bootFinished(); return NO_ERROR; } - case CAPTURE_SCREEN: { + case CAPTURE_DISPLAY: { CHECK_INTERFACE(ISurfaceComposer, data, reply); - sp<IBinder> display = data.readStrongBinder(); - ui::Dataspace reqDataspace = static_cast<ui::Dataspace>(data.readInt32()); - ui::PixelFormat reqPixelFormat = static_cast<ui::PixelFormat>(data.readInt32()); - sp<GraphicBuffer> outBuffer; - Rect sourceCrop(Rect::EMPTY_RECT); - data.read(sourceCrop); - uint32_t reqWidth = data.readUint32(); - uint32_t reqHeight = data.readUint32(); - bool useIdentityTransform = static_cast<bool>(data.readInt32()); - int32_t rotation = data.readInt32(); - bool captureSecureLayers = static_cast<bool>(data.readInt32()); - - bool capturedSecureLayers = false; - status_t res = captureScreen(display, &outBuffer, capturedSecureLayers, reqDataspace, - reqPixelFormat, sourceCrop, reqWidth, reqHeight, - useIdentityTransform, ui::toRotation(rotation), - captureSecureLayers); + DisplayCaptureArgs args; + ScreenCaptureResults captureResults; + + status_t res = args.read(data); + if (res != NO_ERROR) { + reply->writeInt32(res); + return NO_ERROR; + } + + res = captureDisplay(args, captureResults); reply->writeInt32(res); if (res == NO_ERROR) { - reply->write(*outBuffer); - reply->writeBool(capturedSecureLayers); + captureResults.write(*reply); } return NO_ERROR; } - case CAPTURE_SCREEN_BY_ID: { + case CAPTURE_DISPLAY_BY_ID: { CHECK_INTERFACE(ISurfaceComposer, data, reply); uint64_t displayOrLayerStack = data.readUint64(); - ui::Dataspace outDataspace = ui::Dataspace::V0_SRGB; - sp<GraphicBuffer> outBuffer; - status_t res = captureScreen(displayOrLayerStack, &outDataspace, &outBuffer); + ScreenCaptureResults captureResults; + status_t res = captureDisplay(displayOrLayerStack, captureResults); reply->writeInt32(res); if (res == NO_ERROR) { - reply->writeInt32(static_cast<int32_t>(outDataspace)); - reply->write(*outBuffer); + captureResults.write(*reply); } return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 229a5c2e62..2982a99859 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1922,19 +1922,31 @@ status_t SurfaceComposerClient::setGlobalShadowSettings(const half4& ambientColo // ---------------------------------------------------------------------------- -status_t ScreenshotClient::capture(const sp<IBinder>& display, ui::Dataspace reqDataSpace, +status_t ScreenshotClient::capture(const sp<IBinder>& display, ui::Dataspace /* reqDataspace */, ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, ui::Rotation rotation, bool captureSecureLayers, sp<GraphicBuffer>* outBuffer, bool& outCapturedSecureLayers) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == nullptr) return NO_INIT; - status_t ret = s->captureScreen(display, outBuffer, outCapturedSecureLayers, reqDataSpace, - reqPixelFormat, sourceCrop, reqWidth, reqHeight, - useIdentityTransform, rotation, captureSecureLayers); + + DisplayCaptureArgs args; + args.displayToken = display; + args.pixelFormat = reqPixelFormat; + args.sourceCrop = sourceCrop; + args.width = reqWidth; + args.height = reqHeight; + args.useIdentityTransform = useIdentityTransform; + args.rotation = rotation; + args.captureSecureLayers = captureSecureLayers; + + ScreenCaptureResults captureResults; + status_t ret = s->captureDisplay(args, captureResults); if (ret != NO_ERROR) { return ret; } + *outBuffer = captureResults.buffer; + outCapturedSecureLayers = captureResults.capturedSecureLayers; return ret; } @@ -1951,7 +1963,11 @@ status_t ScreenshotClient::capture(uint64_t displayOrLayerStack, ui::Dataspace* sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == nullptr) return NO_INIT; - return s->captureScreen(displayOrLayerStack, outDataspace, outBuffer); + ScreenCaptureResults captureResults; + status_t ret = s->captureDisplay(displayOrLayerStack, captureResults); + *outBuffer = captureResults.buffer; + *outDataspace = captureResults.capturedDataspace; + return ret; } status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, ui::Dataspace reqDataSpace, diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 645714a915..c0cafc5715 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -48,11 +48,14 @@ namespace android { struct client_cache_t; struct ComposerState; +struct DisplayCaptureArgs; struct DisplayConfig; struct DisplayInfo; struct DisplayStatInfo; struct DisplayState; struct InputWindowCommands; +struct LayerCaptureArgs; +struct ScreenCaptureResults; class LayerDebugInfo; class HdrCapabilities; class IDisplayEventConnection; @@ -246,65 +249,17 @@ public: /** * Capture the specified screen. This requires READ_FRAME_BUFFER * permission. This function will fail if there is a secure window on - * screen. + * screen and DisplayCaptureArgs.captureSecureLayers is false. * * This function can capture a subregion (the source crop) of the screen. * The subregion can be optionally rotated. It will also be scaled to * match the size of the output buffer. - * - * reqDataspace and reqPixelFormat specify the data space and pixel format - * of the buffer. The caller should pick the data space and pixel format - * that it can consume. - * - * sourceCrop is the crop on the logical display. - * - * reqWidth and reqHeight specifies the size of the buffer. When either - * of them is 0, they are set to the size of the logical display viewport. - * - * When useIdentityTransform is true, layer transformations are disabled. - * - * rotation specifies the rotation of the source crop (and the pixels in - * it) around its center. - */ - virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer, - bool& outCapturedSecureLayers, ui::Dataspace reqDataspace, - ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, - uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - ui::Rotation rotation = ui::ROTATION_0, - bool captureSecureLayers = false) = 0; - /** - * Capture the specified screen. This requires READ_FRAME_BUFFER - * permission. This function will fail if there is a secure window on - * screen. - * - * This function can capture a subregion (the source crop) of the screen - * into an sRGB buffer with RGBA_8888 pixel format. - * The subregion can be optionally rotated. It will also be scaled to - * match the size of the output buffer. - * - * At the moment, sourceCrop is ignored and is always set to the visible - * region (projected display viewport) of the screen. - * - * reqWidth and reqHeight specifies the size of the buffer. When either - * of them is 0, they are set to the size of the logical display viewport. - * - * When useIdentityTransform is true, layer transformations are disabled. - * - * rotation specifies the rotation of the source crop (and the pixels in - * it) around its center. - */ - virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer, - const Rect& sourceCrop, uint32_t reqWidth, uint32_t reqHeight, - bool useIdentityTransform, - ui::Rotation rotation = ui::ROTATION_0) { - bool outIgnored; - return captureScreen(display, outBuffer, outIgnored, ui::Dataspace::V0_SRGB, - ui::PixelFormat::RGBA_8888, sourceCrop, reqWidth, reqHeight, - useIdentityTransform, rotation); - } + */ + virtual status_t captureDisplay(const DisplayCaptureArgs& args, + ScreenCaptureResults& captureResults) = 0; - virtual status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace, - sp<GraphicBuffer>* outBuffer) = 0; + virtual status_t captureDisplay(uint64_t displayOrLayerStack, + ScreenCaptureResults& captureResults) = 0; template <class AA> struct SpHash { @@ -562,7 +517,7 @@ public: GET_DISPLAY_CONFIGS, GET_ACTIVE_CONFIG, GET_DISPLAY_STATE, - CAPTURE_SCREEN, + CAPTURE_DISPLAY, CAPTURE_LAYERS, CLEAR_ANIMATION_FRAME_STATS, GET_ANIMATION_FRAME_STATS, @@ -590,7 +545,7 @@ public: GET_DESIRED_DISPLAY_CONFIG_SPECS, GET_DISPLAY_BRIGHTNESS_SUPPORT, SET_DISPLAY_BRIGHTNESS, - CAPTURE_SCREEN_BY_ID, + CAPTURE_DISPLAY_BY_ID, NOTIFY_POWER_BOOST, SET_GLOBAL_SHADOW_SETTINGS, GET_AUTO_LOW_LATENCY_MODE_SUPPORT, diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index da5bbdd2e6..d88c477580 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -120,6 +120,8 @@ protected: .show(mSurfaceControl) .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB) .apply(); + + mCaptureArgs.displayToken = mDisplayToken; } void setUpProducer(BLASTBufferQueueHelper adapter, sp<IGraphicBufferProducer>& producer) { @@ -165,14 +167,15 @@ protected: void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0, bool outsideRegion = false) { + sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer; const auto epsilon = 3; - const auto width = mScreenCaptureBuf->getWidth(); - const auto height = mScreenCaptureBuf->getHeight(); - const auto stride = mScreenCaptureBuf->getStride(); + const auto width = captureBuf->getWidth(); + const auto height = captureBuf->getHeight(); + const auto stride = captureBuf->getStride(); uint32_t* bufData; - mScreenCaptureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN), - reinterpret_cast<void**>(&bufData)); + captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN), + reinterpret_cast<void**>(&bufData)); for (uint32_t row = 0; row < height; row++) { for (uint32_t col = 0; col < width; col++) { @@ -196,7 +199,7 @@ protected: } } } - mScreenCaptureBuf->unlock(); + captureBuf->unlock(); ASSERT_EQ(false, ::testing::Test::HasFailure()); } @@ -206,10 +209,12 @@ protected: sp<IBinder> mDisplayToken; sp<SurfaceControl> mSurfaceControl; - sp<GraphicBuffer> mScreenCaptureBuf; uint32_t mDisplayWidth; uint32_t mDisplayHeight; + + DisplayCaptureArgs mCaptureArgs; + ScreenCaptureResults mCaptureResults; }; TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) { @@ -301,12 +306,7 @@ TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) { adapter.waitForCallbacks(); // capture screen and verify that it is red - bool capturedSecureLayers; - ASSERT_EQ(NO_ERROR, - mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers, - ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(), - mDisplayWidth, mDisplayHeight, - /*useIdentityTransform*/ false)); + ASSERT_EQ(NO_ERROR, mComposer->captureDisplay(mCaptureArgs, mCaptureResults)); ASSERT_NO_FATAL_FAILURE( checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); } @@ -383,12 +383,8 @@ TEST_F(BLASTBufferQueueTest, SetCrop_Item) { adapter.waitForCallbacks(); // capture screen and verify that it is red - bool capturedSecureLayers; - ASSERT_EQ(NO_ERROR, - mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers, - ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(), - mDisplayWidth, mDisplayHeight, - /*useIdentityTransform*/ false)); + ASSERT_EQ(NO_ERROR, mComposer->captureDisplay(mCaptureArgs, mCaptureResults)); + ASSERT_NO_FATAL_FAILURE( checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); } @@ -444,12 +440,8 @@ TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { adapter.waitForCallbacks(); // capture screen and verify that it is red - bool capturedSecureLayers; - ASSERT_EQ(NO_ERROR, - mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers, - ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(), - mDisplayWidth, mDisplayHeight, - /*useIdentityTransform*/ false)); + ASSERT_EQ(NO_ERROR, mComposer->captureDisplay(mCaptureArgs, mCaptureResults)); + ASSERT_NO_FATAL_FAILURE( checkScreenCapture(r, g, b, {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength})); @@ -489,12 +481,8 @@ public: ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint); adapter.waitForCallbacks(); - bool capturedSecureLayers; - ASSERT_EQ(NO_ERROR, - mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers, - ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, - Rect(), mDisplayWidth, mDisplayHeight, - /*useIdentityTransform*/ false)); + ASSERT_EQ(NO_ERROR, mComposer->captureDisplay(mCaptureArgs, mCaptureResults)); + switch (tr) { case ui::Transform::ROT_0: ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0, diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index d41a63053b..bf8aed6677 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -244,11 +244,13 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersDontSucceed) { const sp<IBinder> display = sf->getInternalDisplayToken(); ASSERT_FALSE(display == nullptr); - sp<GraphicBuffer> outBuffer; - bool ignored; - ASSERT_EQ(NO_ERROR, - sf->captureScreen(display, &outBuffer, ignored, ui::Dataspace::V0_SRGB, - ui::PixelFormat::RGBA_8888, Rect(), 64, 64, false)); + DisplayCaptureArgs captureArgs; + captureArgs.displayToken = display; + captureArgs.width = 64; + captureArgs.height = 64; + + ScreenCaptureResults captureResults; + ASSERT_EQ(NO_ERROR, sf->captureDisplay(captureArgs, captureResults)); ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(), NATIVE_WINDOW_API_CPU)); @@ -278,9 +280,7 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersDontSucceed) { &buf)); ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1)); } - ASSERT_EQ(NO_ERROR, - sf->captureScreen(display, &outBuffer, ignored, ui::Dataspace::V0_SRGB, - ui::PixelFormat::RGBA_8888, Rect(), 64, 64, false)); + ASSERT_EQ(NO_ERROR, sf->captureDisplay(captureArgs, captureResults)); } TEST_F(SurfaceTest, ConcreteTypeIsSurface) { @@ -742,12 +742,8 @@ public: } status_t setActiveColorMode(const sp<IBinder>& /*display*/, ColorMode /*colorMode*/) override { return NO_ERROR; } - status_t captureScreen(const sp<IBinder>& /*display*/, sp<GraphicBuffer>* /*outBuffer*/, - bool& /*outCapturedSecureLayers*/, ui::Dataspace /*reqDataspace*/, - ui::PixelFormat /*reqPixelFormat*/, const Rect& /*sourceCrop*/, - uint32_t /*reqWidth*/, uint32_t /*reqHeight*/, - bool /*useIdentityTransform*/, ui::Rotation, - bool /*captureSecureLayers*/) override { + status_t captureDisplay(const DisplayCaptureArgs& /* captureArgs */, + ScreenCaptureResults& /* captureResults */) override { return NO_ERROR; } status_t getAutoLowLatencyModeSupport(const sp<IBinder>& /*display*/, @@ -760,8 +756,8 @@ public: return NO_ERROR; } void setGameContentType(const sp<IBinder>& /*display*/, bool /*on*/) override {} - status_t captureScreen(uint64_t /*displayOrLayerStack*/, ui::Dataspace* /*outDataspace*/, - sp<GraphicBuffer>* /*outBuffer*/) override { + status_t captureDisplay(uint64_t /*displayOrLayerStack*/, + ScreenCaptureResults& /* captureResults */) override { return NO_ERROR; } virtual status_t captureLayers( diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index aba58618bb..334812e96a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4969,7 +4969,7 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { return OK; } case CAPTURE_LAYERS: - case CAPTURE_SCREEN: + case CAPTURE_DISPLAY: case ADD_REGION_SAMPLING_LISTENER: case REMOVE_REGION_SAMPLING_LISTENER: { // codes that require permission check @@ -4983,7 +4983,7 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { } return OK; } - case CAPTURE_SCREEN_BY_ID: { + case CAPTURE_DISPLAY_BY_ID: { IPCThreadState* ipc = IPCThreadState::self(); const int uid = ipc->getCallingUid(); if (uid == AID_ROOT || uid == AID_GRAPHICS || uid == AID_SYSTEM || uid == AID_SHELL) { @@ -5429,61 +5429,64 @@ private: const int mApi; }; -status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken, - sp<GraphicBuffer>* outBuffer, bool& outCapturedSecureLayers, - Dataspace reqDataspace, ui::PixelFormat reqPixelFormat, - const Rect& sourceCrop, uint32_t reqWidth, - uint32_t reqHeight, bool useIdentityTransform, - ui::Rotation rotation, bool captureSecureLayers) { +static Dataspace pickDataspaceFromColorMode(const ColorMode colorMode) { + switch (colorMode) { + case ColorMode::DISPLAY_P3: + case ColorMode::BT2100_PQ: + case ColorMode::BT2100_HLG: + case ColorMode::DISPLAY_BT2020: + return Dataspace::DISPLAY_P3; + default: + return Dataspace::V0_SRGB; + } +} + +status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, + ScreenCaptureResults& captureResults) { ATRACE_CALL(); - if (!displayToken) return BAD_VALUE; + if (!args.displayToken) return BAD_VALUE; - auto renderAreaRotation = ui::Transform::toRotationFlags(rotation); + auto renderAreaRotation = ui::Transform::toRotationFlags(args.rotation); if (renderAreaRotation == ui::Transform::ROT_INVALID) { - ALOGE("%s: Invalid rotation: %s", __FUNCTION__, toCString(rotation)); + ALOGE("%s: Invalid rotation: %s", __FUNCTION__, toCString(args.rotation)); renderAreaRotation = ui::Transform::ROT_0; } wp<DisplayDevice> displayWeak; ui::LayerStack layerStack; - ui::Size reqSize(reqWidth, reqHeight); + ui::Size reqSize(args.width, args.height); + ui::Dataspace dataspace; { Mutex::Autolock lock(mStateLock); - sp<DisplayDevice> display = getDisplayDeviceLocked(displayToken); + sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken); if (!display) return NAME_NOT_FOUND; displayWeak = display; layerStack = display->getLayerStack(); // set the requested width/height to the logical display viewport size // by default - if (reqWidth == 0 || reqHeight == 0) { + if (args.width == 0 || args.height == 0) { reqSize = display->getViewport().getSize(); } + + const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode; + dataspace = pickDataspaceFromColorMode(colorMode); } RenderAreaFuture renderAreaFuture = promise::defer([=] { - return DisplayRenderArea::create(displayWeak, sourceCrop, reqSize, reqDataspace, - renderAreaRotation, captureSecureLayers); + return DisplayRenderArea::create(displayWeak, args.sourceCrop, reqSize, dataspace, + renderAreaRotation, args.captureSecureLayers); }); auto traverseLayers = [this, layerStack](const LayerVector::Visitor& visitor) { traverseLayersInLayerStack(layerStack, visitor); }; - return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize, outBuffer, - reqPixelFormat, useIdentityTransform, outCapturedSecureLayers); -} -static Dataspace pickDataspaceFromColorMode(const ColorMode colorMode) { - switch (colorMode) { - case ColorMode::DISPLAY_P3: - case ColorMode::BT2100_PQ: - case ColorMode::BT2100_HLG: - case ColorMode::DISPLAY_BT2020: - return Dataspace::DISPLAY_P3; - default: - return Dataspace::V0_SRGB; - } + captureResults.capturedDataspace = dataspace; + return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize, + &captureResults.buffer, args.pixelFormat, args.useIdentityTransform, + captureResults.capturedSecureLayers); } status_t SurfaceFlinger::setSchedFifo(bool enabled) { @@ -5525,8 +5528,8 @@ sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) { return nullptr; } -status_t SurfaceFlinger::captureScreen(uint64_t displayOrLayerStack, Dataspace* outDataspace, - sp<GraphicBuffer>* outBuffer) { +status_t SurfaceFlinger::captureDisplay(uint64_t displayOrLayerStack, + ScreenCaptureResults& captureResults) { ui::LayerStack layerStack; wp<DisplayDevice> displayWeak; ui::Size size; @@ -5562,24 +5565,24 @@ status_t SurfaceFlinger::captureScreen(uint64_t displayOrLayerStack, Dataspace* default: break; } - *outDataspace = + captureResults.capturedDataspace = pickDataspaceFromColorMode(display->getCompositionDisplay()->getState().colorMode); } RenderAreaFuture renderAreaFuture = promise::defer([=] { - return DisplayRenderArea::create(displayWeak, Rect(), size, *outDataspace, - captureOrientation, false /* captureSecureLayers */); + return DisplayRenderArea::create(displayWeak, Rect(), size, + captureResults.capturedDataspace, captureOrientation, + false /* captureSecureLayers */); }); auto traverseLayers = [this, layerStack](const LayerVector::Visitor& visitor) { traverseLayersInLayerStack(layerStack, visitor); }; - bool ignored = false; - - return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size, outBuffer, - ui::PixelFormat::RGBA_8888, false /* useIdentityTransform */, - ignored /* outCapturedSecureLayers */); + return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size, + &captureResults.buffer, ui::PixelFormat::RGBA_8888, + false /* useIdentityTransform */, + captureResults.capturedSecureLayers); } status_t SurfaceFlinger::captureLayers( diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 2c4e40d73a..55f803401d 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -433,13 +433,10 @@ private: ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp, ISurfaceComposer::ConfigChanged configChanged = ISurfaceComposer::eConfigChangedSuppress) override; - status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer, - bool& outCapturedSecureLayers, ui::Dataspace reqDataspace, - ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, - uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - ui::Rotation rotation, bool captureSecureLayers) override; - status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace, - sp<GraphicBuffer>* outBuffer) override; + status_t captureDisplay(const DisplayCaptureArgs& args, + ScreenCaptureResults& captureResults) override; + status_t captureDisplay(uint64_t displayOrLayerStack, + ScreenCaptureResults& captureResults) override; status_t captureLayers( const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer, const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h index f3e11d811c..d4e952aa21 100644 --- a/services/surfaceflinger/tests/LayerTransactionTest.h +++ b/services/surfaceflinger/tests/LayerTransactionTest.h @@ -40,6 +40,8 @@ protected: sp<ISurfaceComposer> sf(ComposerService::getComposerService()); ASSERT_NO_FATAL_FAILURE(sf->getColorManagement(&mColorManagementUsed)); + + mCaptureArgs.displayToken = mDisplay; } virtual void TearDown() { @@ -249,6 +251,9 @@ protected: sp<SurfaceControl> mBlackBgSurface; bool mColorManagementUsed; + DisplayCaptureArgs mCaptureArgs; + ScreenCaptureResults mCaptureResults; + private: void SetUpDisplay() { mDisplay = mClient->getInternalDisplayToken(); diff --git a/services/surfaceflinger/tests/LayerTransaction_test.cpp b/services/surfaceflinger/tests/LayerTransaction_test.cpp index 1f8f7ed892..0ef4150bfe 100644 --- a/services/surfaceflinger/tests/LayerTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTransaction_test.cpp @@ -32,18 +32,16 @@ TEST_F(LayerTransactionTest, SetFlagsSecureEUidSystem) { ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); sp<ISurfaceComposer> composer = ComposerService::getComposerService(); - sp<GraphicBuffer> outBuffer; Transaction() .setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure) .apply(true); - ASSERT_EQ(PERMISSION_DENIED, - composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false)); + ASSERT_EQ(PERMISSION_DENIED, composer->captureDisplay(mCaptureArgs, mCaptureResults)); UIDFaker f(AID_SYSTEM); // By default the system can capture screenshots with secure layers but they // will be blacked out - ASSERT_EQ(NO_ERROR, composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false)); + ASSERT_EQ(NO_ERROR, composer->captureDisplay(mCaptureArgs, mCaptureResults)); { SCOPED_TRACE("as system"); @@ -53,13 +51,12 @@ TEST_F(LayerTransactionTest, SetFlagsSecureEUidSystem) { // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able // to receive them...we are expected to take care with the results. - bool outCapturedSecureLayers; - ASSERT_EQ(NO_ERROR, - composer->captureScreen(mDisplay, &outBuffer, outCapturedSecureLayers, - ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(), 0, - 0, false, ui::ROTATION_0, true)); - ASSERT_EQ(true, outCapturedSecureLayers); - ScreenCapture sc(outBuffer); + DisplayCaptureArgs args; + args.displayToken = mDisplay; + args.captureSecureLayers = true; + ASSERT_EQ(NO_ERROR, composer->captureDisplay(args, mCaptureResults)); + ASSERT_EQ(true, mCaptureResults.capturedSecureLayers); + ScreenCapture sc(mCaptureResults.buffer); sc.expectColor(Rect(0, 0, 32, 32), Color::RED); } diff --git a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp index 84780ba73b..2ec4ea48a3 100644 --- a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp @@ -170,11 +170,15 @@ TEST_P(LayerTypeTransactionTest, SetFlagsSecure) { Transaction() .setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure) .apply(true); - ASSERT_EQ(PERMISSION_DENIED, - composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false)); + + DisplayCaptureArgs args; + args.displayToken = mDisplay; + + ScreenCaptureResults captureResults; + ASSERT_EQ(PERMISSION_DENIED, composer->captureDisplay(args, captureResults)); Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true); - ASSERT_EQ(NO_ERROR, composer->captureScreen(mDisplay, &outBuffer, Rect(), 0, 0, false)); + ASSERT_EQ(NO_ERROR, composer->captureDisplay(args, captureResults)); } TEST_P(LayerTypeTransactionTest, RefreshRateIsInitialized) { sp<SurfaceControl> layer; diff --git a/services/surfaceflinger/tests/utils/ScreenshotUtils.h b/services/surfaceflinger/tests/utils/ScreenshotUtils.h index 5480b00a4d..ffdf55b687 100644 --- a/services/surfaceflinger/tests/utils/ScreenshotUtils.h +++ b/services/surfaceflinger/tests/utils/ScreenshotUtils.h @@ -35,9 +35,12 @@ public: const auto sf = ComposerService::getComposerService(); SurfaceComposerClient::Transaction().apply(true); - sp<GraphicBuffer> outBuffer; - ASSERT_EQ(NO_ERROR, sf->captureScreen(displayToken, &outBuffer, Rect(), 0, 0, false)); - *sc = std::make_unique<ScreenCapture>(outBuffer); + DisplayCaptureArgs args; + args.displayToken = displayToken; + + ScreenCaptureResults captureResults; + ASSERT_EQ(NO_ERROR, sf->captureDisplay(args, captureResults)); + *sc = std::make_unique<ScreenCapture>(captureResults.buffer); } static void captureLayers(std::unique_ptr<ScreenCapture>* sc, sp<IBinder>& parentHandle, |