Merge "Set window to transparent when screenshotting layer." into pi-dev
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index bedf765..b8a8906 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -287,7 +287,8 @@
rotation) {}
DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqHeight,
uint32_t reqWidth, ISurfaceComposer::Rotation rotation)
- : RenderArea(reqHeight, reqWidth, rotation), mDevice(device), mSourceCrop(sourceCrop) {}
+ : RenderArea(reqHeight, reqWidth, CaptureFill::OPAQUE, rotation), mDevice(device),
+ mSourceCrop(sourceCrop) {}
const Transform& getTransform() const override { return mDevice->getTransform(); }
Rect getBounds() const override { return mDevice->getBounds(); }
diff --git a/services/surfaceflinger/RenderArea.cpp b/services/surfaceflinger/RenderArea.cpp
index 6225df1..46ec8e6 100644
--- a/services/surfaceflinger/RenderArea.cpp
+++ b/services/surfaceflinger/RenderArea.cpp
@@ -2,6 +2,15 @@
namespace android {
+float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
+ switch(captureFill) {
+ case CaptureFill::CLEAR:
+ return 0.0f;
+ case CaptureFill::OPAQUE:
+ default:
+ return 1.0f;
+ }
+}
/*
* Checks that the requested width and height are valid and updates them to the render area
* dimensions if they are set to 0
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index 4f812fc..3630677 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -9,10 +9,15 @@
namespace android {
class RenderArea {
+
public:
- RenderArea(uint32_t reqHeight, uint32_t reqWidth,
+ enum class CaptureFill {CLEAR, OPAQUE};
+
+ static float getCaptureFillValue(CaptureFill captureFill);
+
+ RenderArea(uint32_t reqHeight, uint32_t reqWidth, CaptureFill captureFill,
ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone)
- : mReqHeight(reqHeight), mReqWidth(reqWidth) {
+ : mReqHeight(reqHeight), mReqWidth(reqWidth), mCaptureFill(captureFill) {
mRotationFlags = Transform::fromRotation(rotation);
}
@@ -35,10 +40,13 @@
Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
status_t updateDimensions();
+ CaptureFill getCaptureFill() const { return mCaptureFill; };
+
private:
uint32_t mReqHeight;
uint32_t mReqWidth;
Transform::orientation_flags mRotationFlags;
+ CaptureFill mCaptureFill;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a8680e2..dfde30b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4694,7 +4694,7 @@
public:
LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
int32_t reqWidth, int32_t reqHeight, bool childrenOnly)
- : RenderArea(reqHeight, reqWidth),
+ : RenderArea(reqHeight, reqWidth, CaptureFill::CLEAR),
mLayer(layer),
mCrop(crop),
mFlinger(flinger),
@@ -4929,8 +4929,9 @@
renderArea.getRotationFlags());
engine.disableTexturing();
+ const float alpha = RenderArea::getCaptureFillValue(renderArea.getCaptureFill());
// redraw the screen entirely...
- engine.clearWithColor(0, 0, 0, 1);
+ engine.clearWithColor(0, 0, 0, alpha);
traverseLayers([&](Layer* layer) {
if (filtering) layer->setFiltering(true);
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 176c691..a0f12f1 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -2358,6 +2358,24 @@
mCapture->expectChildColor(0, 0);
}
+TEST_F(ScreenCaptureTest, CaptureTransparent) {
+ sp<SurfaceControl> child =
+ mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+ 0, mFGSurfaceControl.get());
+
+ fillSurfaceRGBA8(child, 200, 200, 200);
+
+ SurfaceComposerClient::Transaction().show(child).apply(true);
+
+ auto childHandle = child->getHandle();
+
+ // Captures child
+ ScreenCapture::captureLayers(&mCapture, childHandle, {0, 0, 10, 20});
+ mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
+ // Area outside of child's bounds is transparent.
+ mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
+}
+
// In the following tests we verify successful skipping of a parent layer,
// so we use the same verification logic and only change how we mutate