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

Commit b6fd2e0d authored by Alan Ding's avatar Alan Ding Committed by Android (Google) Code Review
Browse files

Merge "Reland "ui: Refactor stable ID generation for GPU virtual displays"" into main

parents fe0aa3b5 c9de92a5
Loading
Loading
Loading
Loading
+27 −15
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <ostream>
#include <string>

#include <ftl/hash.h>
#include <ftl/optional.h>

namespace android {
@@ -38,6 +39,9 @@ struct DisplayId {
    constexpr DisplayId(const DisplayId&) = default;
    DisplayId& operator=(const DisplayId&) = default;

    constexpr bool isVirtual() const { return value & FLAG_VIRTUAL; }
    constexpr bool isStable() const { return value & FLAG_STABLE; }

    uint64_t value;

    // For deserialization.
@@ -76,10 +80,10 @@ inline std::ostream& operator<<(std::ostream& stream, DisplayId displayId) {
// DisplayId of a physical display, such as the internal display or externally connected display.
struct PhysicalDisplayId : DisplayId {
    static constexpr ftl::Optional<PhysicalDisplayId> tryCast(DisplayId id) {
        if (id.value & FLAG_VIRTUAL) {
        if (id.isVirtual()) {
            return std::nullopt;
        }
        return {PhysicalDisplayId(id)};
        return PhysicalDisplayId(id);
    }

    // Returns a stable ID based on EDID information.
@@ -117,25 +121,23 @@ struct VirtualDisplayId : DisplayId {
    static constexpr uint64_t FLAG_GPU = 1ULL << 61;

    static constexpr std::optional<VirtualDisplayId> tryCast(DisplayId id) {
        if (id.value & FLAG_VIRTUAL) {
            return {VirtualDisplayId(id)};
        if (id.isVirtual()) {
            return VirtualDisplayId(id);
        }
        return std::nullopt;
    }

protected:
    constexpr VirtualDisplayId(uint64_t flags, BaseId baseId)
          : DisplayId(DisplayId::FLAG_VIRTUAL | flags | baseId) {}

    explicit constexpr VirtualDisplayId(uint64_t value) : DisplayId(FLAG_VIRTUAL | value) {}
    explicit constexpr VirtualDisplayId(DisplayId other) : DisplayId(other) {}
};

struct HalVirtualDisplayId : VirtualDisplayId {
    explicit constexpr HalVirtualDisplayId(BaseId baseId) : VirtualDisplayId(0, baseId) {}
    explicit constexpr HalVirtualDisplayId(BaseId baseId) : VirtualDisplayId(baseId) {}

    static constexpr std::optional<HalVirtualDisplayId> tryCast(DisplayId id) {
        if ((id.value & FLAG_VIRTUAL) && !(id.value & VirtualDisplayId::FLAG_GPU)) {
            return {HalVirtualDisplayId(id)};
        if (id.isVirtual() && !(id.value & FLAG_GPU)) {
            return HalVirtualDisplayId(id);
        }
        return std::nullopt;
    }
@@ -145,17 +147,27 @@ private:
};

struct GpuVirtualDisplayId : VirtualDisplayId {
    explicit constexpr GpuVirtualDisplayId(BaseId baseId)
          : VirtualDisplayId(VirtualDisplayId::FLAG_GPU, baseId) {}
    explicit constexpr GpuVirtualDisplayId(BaseId baseId) : VirtualDisplayId(FLAG_GPU | baseId) {}

    static constexpr std::optional<GpuVirtualDisplayId> fromUniqueId(const std::string& uniqueId) {
        if (const auto hashOpt = ftl::stable_hash(uniqueId)) {
            return GpuVirtualDisplayId(HashTag{}, *hashOpt);
        }
        return {};
    }

    static constexpr std::optional<GpuVirtualDisplayId> tryCast(DisplayId id) {
        if ((id.value & FLAG_VIRTUAL) && (id.value & VirtualDisplayId::FLAG_GPU)) {
            return {GpuVirtualDisplayId(id)};
        if (id.isVirtual() && (id.value & FLAG_GPU)) {
            return GpuVirtualDisplayId(id);
        }
        return std::nullopt;
    }

private:
    struct HashTag {}; // Disambiguate with BaseId constructor.
    constexpr GpuVirtualDisplayId(HashTag, uint64_t hash)
          : VirtualDisplayId(FLAG_STABLE | FLAG_GPU | hash) {}

    explicit constexpr GpuVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
};

@@ -169,7 +181,7 @@ struct HalDisplayId : DisplayId {
        if (GpuVirtualDisplayId::tryCast(id)) {
            return std::nullopt;
        }
        return {HalDisplayId(id)};
        return HalDisplayId(id);
    }

private:
+43 −4
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ TEST(DisplayIdTest, createPhysicalIdFromEdid) {
    constexpr uint8_t port = 1;
    constexpr uint16_t manufacturerId = 13;
    constexpr uint32_t modelHash = 42;
    PhysicalDisplayId id = PhysicalDisplayId::fromEdid(port, manufacturerId, modelHash);
    const PhysicalDisplayId id = PhysicalDisplayId::fromEdid(port, manufacturerId, modelHash);
    EXPECT_EQ(port, id.getPort());
    EXPECT_EQ(manufacturerId, id.getManufacturerId());
    EXPECT_FALSE(VirtualDisplayId::tryCast(id));
@@ -39,7 +39,7 @@ TEST(DisplayIdTest, createPhysicalIdFromEdid) {

TEST(DisplayIdTest, createPhysicalIdFromPort) {
    constexpr uint8_t port = 3;
    PhysicalDisplayId id = PhysicalDisplayId::fromPort(port);
    const PhysicalDisplayId id = PhysicalDisplayId::fromPort(port);
    EXPECT_EQ(port, id.getPort());
    EXPECT_FALSE(VirtualDisplayId::tryCast(id));
    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
@@ -52,7 +52,34 @@ TEST(DisplayIdTest, createPhysicalIdFromPort) {
}

TEST(DisplayIdTest, createGpuVirtualId) {
    GpuVirtualDisplayId id(42);
    const GpuVirtualDisplayId id(42);
    EXPECT_TRUE(VirtualDisplayId::tryCast(id));
    EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
    EXPECT_FALSE(HalDisplayId::tryCast(id));

    EXPECT_EQ(id, DisplayId::fromValue(id.value));
    EXPECT_EQ(id, DisplayId::fromValue<GpuVirtualDisplayId>(id.value));
}

TEST(DisplayIdTest, createVirtualIdFromGpuVirtualId) {
    const VirtualDisplayId id(GpuVirtualDisplayId(42));
    EXPECT_TRUE(VirtualDisplayId::tryCast(id));
    EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
    EXPECT_FALSE(HalDisplayId::tryCast(id));

    const bool isGpuVirtualId = (id.value & VirtualDisplayId::FLAG_GPU);
    EXPECT_EQ((id.isVirtual() && isGpuVirtualId), GpuVirtualDisplayId::tryCast(id).has_value());
}

TEST(DisplayIdTest, createGpuVirtualIdFromUniqueId) {
    static const std::string kUniqueId("virtual:ui:DisplayId_test");
    const auto idOpt = GpuVirtualDisplayId::fromUniqueId(kUniqueId);
    ASSERT_TRUE(idOpt.has_value());
    const GpuVirtualDisplayId id = idOpt.value();
    EXPECT_TRUE(VirtualDisplayId::tryCast(id));
    EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
@@ -64,7 +91,7 @@ TEST(DisplayIdTest, createGpuVirtualId) {
}

TEST(DisplayIdTest, createHalVirtualId) {
    HalVirtualDisplayId id(42);
    const HalVirtualDisplayId id(42);
    EXPECT_TRUE(VirtualDisplayId::tryCast(id));
    EXPECT_TRUE(HalVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
@@ -75,4 +102,16 @@ TEST(DisplayIdTest, createHalVirtualId) {
    EXPECT_EQ(id, DisplayId::fromValue<HalVirtualDisplayId>(id.value));
}

TEST(DisplayIdTest, createVirtualIdFromHalVirtualId) {
    const VirtualDisplayId id(HalVirtualDisplayId(42));
    EXPECT_TRUE(VirtualDisplayId::tryCast(id));
    EXPECT_TRUE(HalVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
    EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
    EXPECT_TRUE(HalDisplayId::tryCast(id));

    const bool isGpuVirtualId = (id.value & VirtualDisplayId::FLAG_GPU);
    EXPECT_EQ((id.isVirtual() && !isGpuVirtualId), HalVirtualDisplayId::tryCast(id).has_value());
}

} // namespace android::ui
+1 −1
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ void Display::setSecure(bool secure) {
}

bool Display::isVirtual() const {
    return VirtualDisplayId::tryCast(mId).has_value();
    return mId.isVirtual();
}

std::optional<DisplayId> Display::getDisplayId() const {
+1 −1
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ public:
        return mCompositionDisplay;
    }

    bool isVirtual() const { return VirtualDisplayId::tryCast(getId()).has_value(); }
    bool isVirtual() const { return getId().isVirtual(); }
    bool isPrimary() const { return mIsPrimary; }

    // isSecure indicates whether this display can be trusted to display