195 lines
7.8 KiB
C++
195 lines
7.8 KiB
C++
#include <gmock/gmock.h>
|
|
#include <gtest/gtest.h>
|
|
#include <gui/LayerMetadata.h>
|
|
|
|
#include "TestableSurfaceFlinger.h"
|
|
|
|
namespace android {
|
|
|
|
using testing::_;
|
|
using testing::Return;
|
|
|
|
class SurfaceFlingerUpdateLayerMetadataSnapshotTest : public testing::Test {
|
|
public:
|
|
SurfaceFlingerUpdateLayerMetadataSnapshotTest() { mFlinger.setupMockScheduler(); }
|
|
|
|
protected:
|
|
sp<Layer> createLayer(const char* name, LayerMetadata& inOutlayerMetadata) {
|
|
LayerCreationArgs args =
|
|
LayerCreationArgs{mFlinger.flinger(), nullptr, name, 0, inOutlayerMetadata};
|
|
inOutlayerMetadata = args.metadata;
|
|
return sp<Layer>::make(args);
|
|
}
|
|
|
|
TestableSurfaceFlinger mFlinger;
|
|
};
|
|
|
|
class LayerMetadataBuilder {
|
|
public:
|
|
LayerMetadataBuilder(LayerMetadata layerMetadata = {}) : mLayerMetadata(layerMetadata) {}
|
|
|
|
LayerMetadataBuilder& setInt32(uint32_t key, int32_t value) {
|
|
mLayerMetadata.setInt32(key, value);
|
|
return *this;
|
|
}
|
|
|
|
LayerMetadata build() { return mLayerMetadata; }
|
|
|
|
private:
|
|
LayerMetadata mLayerMetadata;
|
|
};
|
|
|
|
bool operator==(const LayerMetadata& lhs, const LayerMetadata& rhs) {
|
|
return lhs.mMap == rhs.mMap;
|
|
}
|
|
|
|
std::ostream& operator<<(std::ostream& stream, const LayerMetadata& layerMetadata) {
|
|
stream << "LayerMetadata{";
|
|
for (auto it = layerMetadata.mMap.cbegin(); it != layerMetadata.mMap.cend(); it++) {
|
|
if (it != layerMetadata.mMap.cbegin()) {
|
|
stream << ", ";
|
|
}
|
|
stream << layerMetadata.itemToString(it->first, ":");
|
|
}
|
|
return stream << "}";
|
|
}
|
|
|
|
// Test that the snapshot's layer metadata is set.
|
|
TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, updatesSnapshotMetadata) {
|
|
auto layerMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 1).build();
|
|
auto layer = createLayer("layer", layerMetadata);
|
|
mFlinger.mutableDrawingState().layersSortedByZ.add(layer);
|
|
|
|
mFlinger.updateLayerMetadataSnapshot();
|
|
|
|
EXPECT_EQ(layer->getLayerSnapshot()->layerMetadata, layerMetadata);
|
|
}
|
|
|
|
// Test that snapshot layer metadata is set by merging the child's metadata on top of its
|
|
// parent's metadata.
|
|
TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, mergesSnapshotMetadata) {
|
|
auto layerAMetadata = LayerMetadataBuilder()
|
|
.setInt32(METADATA_OWNER_UID, 1)
|
|
.setInt32(METADATA_TASK_ID, 2)
|
|
.build();
|
|
auto layerA = createLayer("parent", layerAMetadata);
|
|
auto layerBMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 3).build();
|
|
auto layerB = createLayer("child", layerBMetadata);
|
|
layerA->addChild(layerB);
|
|
layerA->commitChildList();
|
|
mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
|
|
|
|
mFlinger.updateLayerMetadataSnapshot();
|
|
|
|
EXPECT_EQ(layerA->getLayerSnapshot()->layerMetadata, layerAMetadata);
|
|
auto expectedChildMetadata =
|
|
LayerMetadataBuilder(layerAMetadata).setInt32(METADATA_TASK_ID, 3).build();
|
|
EXPECT_EQ(layerB->getLayerSnapshot()->layerMetadata, expectedChildMetadata);
|
|
}
|
|
|
|
// Test that snapshot relative layer metadata is set to the parent's layer metadata merged on top of
|
|
// that parent's relative layer metadata.
|
|
TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, updatesRelativeMetadata) {
|
|
auto layerAMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 1).build();
|
|
auto layerA = createLayer("relative-parent", layerAMetadata);
|
|
auto layerAHandle = layerA->getHandle();
|
|
auto layerBMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 2).build();
|
|
auto layerB = createLayer("relative-child", layerBMetadata);
|
|
layerB->setRelativeLayer(layerAHandle, 1);
|
|
mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
|
|
mFlinger.mutableDrawingState().layersSortedByZ.add(layerB);
|
|
|
|
mFlinger.updateLayerMetadataSnapshot();
|
|
|
|
EXPECT_EQ(layerA->getLayerSnapshot()->relativeLayerMetadata, LayerMetadata{});
|
|
EXPECT_EQ(layerB->getLayerSnapshot()->relativeLayerMetadata, layerAMetadata);
|
|
}
|
|
|
|
// Test that snapshot relative layer metadata is set correctly when a layer is interleaved within
|
|
// two other layers.
|
|
//
|
|
// Layer
|
|
// A
|
|
// / \
|
|
// B D
|
|
// /
|
|
// C
|
|
//
|
|
// Z-order Relatives
|
|
// B <- D <- C
|
|
TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, updatesRelativeMetadataInterleaved) {
|
|
auto layerAMetadata = LayerMetadataBuilder().setInt32(METADATA_OWNER_UID, 1).build();
|
|
auto layerA = createLayer("layer-a", layerAMetadata);
|
|
auto layerBMetadata = LayerMetadataBuilder()
|
|
.setInt32(METADATA_TASK_ID, 2)
|
|
.setInt32(METADATA_OWNER_PID, 3)
|
|
.build();
|
|
auto layerB = createLayer("layer-b", layerBMetadata);
|
|
auto layerBHandle = layerB->getHandle();
|
|
LayerMetadata layerCMetadata;
|
|
auto layerC = createLayer("layer-c", layerCMetadata);
|
|
auto layerDMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 4).build();
|
|
auto layerD = createLayer("layer-d", layerDMetadata);
|
|
auto layerDHandle = layerD->getHandle();
|
|
layerB->addChild(layerC);
|
|
layerA->addChild(layerB);
|
|
layerA->addChild(layerD);
|
|
layerC->setRelativeLayer(layerDHandle, 1);
|
|
layerD->setRelativeLayer(layerBHandle, 1);
|
|
layerA->commitChildList();
|
|
mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
|
|
|
|
mFlinger.updateLayerMetadataSnapshot();
|
|
|
|
auto expectedLayerDRelativeMetadata =
|
|
LayerMetadataBuilder()
|
|
// From layer A, parent of relative parent
|
|
.setInt32(METADATA_OWNER_UID, 1)
|
|
// From layer B, relative parent
|
|
.setInt32(METADATA_TASK_ID, 2)
|
|
.setInt32(METADATA_OWNER_PID, 3)
|
|
// added by layer creation args
|
|
.setInt32(gui::METADATA_CALLING_UID,
|
|
layerDMetadata.getInt32(gui::METADATA_CALLING_UID, 0))
|
|
.build();
|
|
EXPECT_EQ(layerD->getLayerSnapshot()->relativeLayerMetadata, expectedLayerDRelativeMetadata);
|
|
auto expectedLayerCRelativeMetadata =
|
|
LayerMetadataBuilder()
|
|
// From layer A, parent of relative parent
|
|
.setInt32(METADATA_OWNER_UID, 1)
|
|
// From layer B, relative parent of relative parent
|
|
.setInt32(METADATA_OWNER_PID, 3)
|
|
// From layer D, relative parent
|
|
.setInt32(METADATA_TASK_ID, 4)
|
|
// added by layer creation args
|
|
.setInt32(gui::METADATA_CALLING_UID,
|
|
layerDMetadata.getInt32(gui::METADATA_CALLING_UID, 0))
|
|
.build();
|
|
EXPECT_EQ(layerC->getLayerSnapshot()->relativeLayerMetadata, expectedLayerCRelativeMetadata);
|
|
}
|
|
|
|
TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest,
|
|
updatesRelativeMetadataMultipleRelativeChildren) {
|
|
auto layerAMetadata = LayerMetadataBuilder().setInt32(METADATA_OWNER_UID, 1).build();
|
|
auto layerA = createLayer("layer-a", layerAMetadata);
|
|
auto layerAHandle = layerA->getHandle();
|
|
LayerMetadata layerBMetadata;
|
|
auto layerB = createLayer("layer-b", layerBMetadata);
|
|
LayerMetadata layerCMetadata;
|
|
auto layerC = createLayer("layer-c", layerCMetadata);
|
|
layerB->setRelativeLayer(layerAHandle, 1);
|
|
layerC->setRelativeLayer(layerAHandle, 2);
|
|
layerA->commitChildList();
|
|
mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
|
|
mFlinger.mutableDrawingState().layersSortedByZ.add(layerB);
|
|
mFlinger.mutableDrawingState().layersSortedByZ.add(layerC);
|
|
|
|
mFlinger.updateLayerMetadataSnapshot();
|
|
|
|
EXPECT_EQ(layerA->getLayerSnapshot()->relativeLayerMetadata, LayerMetadata{});
|
|
EXPECT_EQ(layerB->getLayerSnapshot()->relativeLayerMetadata, layerAMetadata);
|
|
EXPECT_EQ(layerC->getLayerSnapshot()->relativeLayerMetadata, layerAMetadata);
|
|
}
|
|
|
|
} // namespace android
|