Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 74a09f41 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Added ScreenCapture args and results struct"

parents d11e2e66 618c42d4
Loading
Loading
Loading
Loading
+96 −0
Original line number Diff line number Diff line
@@ -498,4 +498,100 @@ bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunc
    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
+42 −0
Original line number Diff line number Diff line
@@ -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 @@ static inline int compare_type(const DisplayState& lhs, const DisplayState& rhs)
// 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
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ cc_test {
        "InvalidHandles_test.cpp",
        "LayerCallback_test.cpp",
        "LayerRenderTypeTransaction_test.cpp",
        "LayerState_test.cpp",
        "LayerTransaction_test.cpp",
        "LayerTypeAndRenderTypeTransaction_test.cpp",
        "LayerTypeTransaction_test.cpp",
+106 −0
Original line number Diff line number Diff line
/*
 * 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