Added ScreenCapture args and results struct
Test: LayerStateTest
Bug: 162367424
Change-Id: I1e1cb5f896a81eea0a4da07d32456a2fb7e0a887
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 117ce58..dd95b92 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -498,4 +498,100 @@
return true;
}
+// ----------------------------------------------------------------------------
+
+status_t CaptureArgs::write(Parcel& output) const {
+ status_t status = output.writeInt32(static_cast<int32_t>(pixelFormat)) ?:
+ output.write(sourceCrop) ?:
+ output.writeFloat(frameScale) ?:
+ output.writeBool(captureSecureLayers);
+ return status;
+}
+
+status_t CaptureArgs::read(const Parcel& input) {
+ int32_t format;
+ status_t status = input.readInt32(&format) ?:
+ input.read(sourceCrop) ?:
+ input.readFloat(&frameScale) ?:
+ input.readBool(&captureSecureLayers);
+
+ pixelFormat = static_cast<ui::PixelFormat>(format);
+ return status;
+}
+
+status_t DisplayCaptureArgs::write(Parcel& output) const {
+ status_t status = CaptureArgs::write(output);
+
+ status |= output.writeStrongBinder(displayToken) ?:
+ output.writeUint32(width) ?:
+ output.writeUint32(height) ?:
+ output.writeBool(useIdentityTransform) ?:
+ output.writeInt32(static_cast<int32_t>(rotation));
+ return status;
+}
+
+status_t DisplayCaptureArgs::read(const Parcel& input) {
+ status_t status = CaptureArgs::read(input);
+
+ int32_t rotationInt;
+
+ status |= input.readStrongBinder(&displayToken) ?:
+ input.readUint32(&width) ?:
+ input.readUint32(&height) ?:
+ input.readBool(&useIdentityTransform) ?:
+ input.readInt32(&rotationInt);
+
+ rotation = ui::toRotation(rotationInt);
+ return status;
+}
+
+status_t LayerCaptureArgs::write(Parcel& output) const {
+ status_t status = CaptureArgs::write(output);
+
+ status |= output.writeStrongBinder(layerHandle);
+ status |= output.writeInt32(excludeHandles.size());
+ for (auto el : excludeHandles) {
+ status |= output.writeStrongBinder(el);
+ }
+ status |= output.writeBool(childrenOnly);
+ return status;
+}
+
+status_t LayerCaptureArgs::read(const Parcel& input) {
+ status_t status = CaptureArgs::read(input);
+
+ status |= input.readStrongBinder(&layerHandle);
+
+ int32_t numExcludeHandles;
+ status |= input.readInt32(&numExcludeHandles);
+ excludeHandles.reserve(numExcludeHandles);
+ for (int i = 0; i < numExcludeHandles; i++) {
+ sp<IBinder> binder;
+ status |= input.readStrongBinder(&binder);
+ excludeHandles.emplace(binder);
+ }
+
+ status |= input.readBool(&childrenOnly);
+ return status;
+}
+
+status_t ScreenCaptureResults::write(Parcel& output) const {
+ status_t status = output.write(*buffer) ?:
+ output.writeBool(capturedSecureLayers) ?:
+ output.writeUint32(static_cast<uint32_t>(capturedDataspace));
+ return status;
+}
+
+status_t ScreenCaptureResults::read(const Parcel& input) {
+ buffer = new GraphicBuffer();
+ uint32_t dataspace;
+ status_t status = input.read(*buffer) ?:
+ input.readBool(&capturedSecureLayers) ?:
+ input.readUint32(&dataspace);
+
+ capturedDataspace = static_cast<ui::Dataspace>(dataspace);
+
+ return status;
+}
+
}; // namespace android
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 41aad0d..de3a9a7 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -30,6 +30,7 @@
#include <input/InputWindow.h>
#endif
+#include <gui/ISurfaceComposer.h>
#include <gui/LayerMetadata.h>
#include <math/vec3.h>
#include <ui/GraphicTypes.h>
@@ -312,6 +313,47 @@
// functionName can be null.
bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* functionName);
+struct CaptureArgs {
+ virtual ~CaptureArgs() = default;
+
+ ui::PixelFormat pixelFormat{ui::PixelFormat::RGBA_8888};
+ Rect sourceCrop;
+ float frameScale{1};
+ bool captureSecureLayers{false};
+
+ virtual status_t write(Parcel& output) const;
+ virtual status_t read(const Parcel& input);
+};
+
+struct DisplayCaptureArgs : CaptureArgs {
+ sp<IBinder> displayToken;
+ uint32_t width{0};
+ uint32_t height{0};
+ bool useIdentityTransform{false};
+ ui::Rotation rotation{ui::ROTATION_0};
+
+ status_t write(Parcel& output) const override;
+ status_t read(const Parcel& input) override;
+};
+
+struct LayerCaptureArgs : CaptureArgs {
+ sp<IBinder> layerHandle;
+ std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>> excludeHandles;
+ bool childrenOnly{true};
+
+ status_t write(Parcel& output) const override;
+ status_t read(const Parcel& input) override;
+};
+
+struct ScreenCaptureResults {
+ sp<GraphicBuffer> buffer;
+ bool capturedSecureLayers{false};
+ ui::Dataspace capturedDataspace{ui::Dataspace::V0_SRGB};
+
+ status_t write(Parcel& output) const;
+ status_t read(const Parcel& input);
+};
+
}; // namespace android
#endif // ANDROID_SF_LAYER_STATE_H
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index c96dfc7..c64abd2 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -27,6 +27,7 @@
"InvalidHandles_test.cpp",
"LayerCallback_test.cpp",
"LayerRenderTypeTransaction_test.cpp",
+ "LayerState_test.cpp",
"LayerTransaction_test.cpp",
"LayerTypeAndRenderTypeTransaction_test.cpp",
"LayerTypeTransaction_test.cpp",
diff --git a/services/surfaceflinger/tests/LayerState_test.cpp b/services/surfaceflinger/tests/LayerState_test.cpp
new file mode 100644
index 0000000..8a49e77
--- /dev/null
+++ b/services/surfaceflinger/tests/LayerState_test.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <binder/Binder.h>
+#include <binder/Parcel.h>
+
+#include <gui/LayerState.h>
+
+namespace android {
+namespace test {
+
+TEST(LayerStateTest, ParcellingDisplayCaptureArgs) {
+ DisplayCaptureArgs args;
+ args.pixelFormat = ui::PixelFormat::RGB_565;
+ args.sourceCrop = Rect(0, 0, 500, 200);
+ args.frameScale = 2;
+ args.captureSecureLayers = true;
+ args.displayToken = new BBinder();
+ args.width = 10;
+ args.height = 20;
+ args.useIdentityTransform = true;
+ args.rotation = ui::ROTATION_90;
+
+ Parcel p;
+ args.write(p);
+ p.setDataPosition(0);
+
+ DisplayCaptureArgs args2;
+ args2.read(p);
+
+ ASSERT_EQ(args.pixelFormat, args2.pixelFormat);
+ ASSERT_EQ(args.sourceCrop, args2.sourceCrop);
+ ASSERT_EQ(args.frameScale, args2.frameScale);
+ ASSERT_EQ(args.captureSecureLayers, args2.captureSecureLayers);
+ ASSERT_EQ(args.displayToken, args2.displayToken);
+ ASSERT_EQ(args.width, args2.width);
+ ASSERT_EQ(args.height, args2.height);
+ ASSERT_EQ(args.useIdentityTransform, args2.useIdentityTransform);
+ ASSERT_EQ(args.rotation, args2.rotation);
+}
+
+TEST(LayerStateTest, ParcellingLayerCaptureArgs) {
+ LayerCaptureArgs args;
+ args.pixelFormat = ui::PixelFormat::RGB_565;
+ args.sourceCrop = Rect(0, 0, 500, 200);
+ args.frameScale = 2;
+ args.captureSecureLayers = true;
+ args.layerHandle = new BBinder();
+ args.excludeHandles = {new BBinder(), new BBinder()};
+ args.childrenOnly = false;
+
+ Parcel p;
+ args.write(p);
+ p.setDataPosition(0);
+
+ LayerCaptureArgs args2;
+ args2.read(p);
+
+ ASSERT_EQ(args.pixelFormat, args2.pixelFormat);
+ ASSERT_EQ(args.sourceCrop, args2.sourceCrop);
+ ASSERT_EQ(args.frameScale, args2.frameScale);
+ ASSERT_EQ(args.captureSecureLayers, args2.captureSecureLayers);
+ ASSERT_EQ(args.layerHandle, args2.layerHandle);
+ ASSERT_EQ(args.excludeHandles, args2.excludeHandles);
+ ASSERT_EQ(args.childrenOnly, args2.childrenOnly);
+}
+
+TEST(LayerStateTest, ParcellingScreenCaptureResults) {
+ ScreenCaptureResults results;
+ results.buffer = new GraphicBuffer(100, 200, PIXEL_FORMAT_RGBA_8888, 1, 0);
+ results.capturedSecureLayers = true;
+ results.capturedDataspace = ui::Dataspace::DISPLAY_P3;
+
+ Parcel p;
+ results.write(p);
+ p.setDataPosition(0);
+
+ ScreenCaptureResults results2;
+ results2.read(p);
+
+ // GraphicBuffer object is reallocated so compare the data in the graphic buffer
+ // rather than the object itself
+ ASSERT_EQ(results.buffer->getWidth(), results2.buffer->getWidth());
+ ASSERT_EQ(results.buffer->getHeight(), results2.buffer->getHeight());
+ ASSERT_EQ(results.buffer->getPixelFormat(), results2.buffer->getPixelFormat());
+ ASSERT_EQ(results.capturedSecureLayers, results2.capturedSecureLayers);
+ ASSERT_EQ(results.capturedDataspace, results2.capturedDataspace);
+}
+
+} // namespace test
+} // namespace android