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

Commit 846a7373 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Add EDID-ID Fabrication Logic" into main

parents e17fc7af 0bf26cdb
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <string>
#include <string_view>

#include <ftl/concat.h>
#include <ftl/hash.h>
#include <log/log.h>
#include <ui/DisplayIdentification.h>
@@ -423,4 +424,27 @@ PhysicalDisplayId getVirtualDisplayId(uint32_t id) {
    return PhysicalDisplayId::fromEdid(0, kVirtualEdidManufacturerId, id);
}

PhysicalDisplayId generateEdidDisplayId(const Edid& edid) {
    const ftl::Concat displayDetailsString{edid.manufacturerId,
                                           edid.productId,
                                           ftl::truncated<13>(edid.displayName),
                                           edid.manufactureWeek,
                                           edid.manufactureOrModelYear,
                                           edid.physicalSizeInCm.getWidth(),
                                           edid.physicalSizeInCm.getHeight()};

    // String has to be cropped to 64 characters (at most) for ftl::stable_hash.
    // This is fine as the accuracy or completeness of the above fields is not
    // critical for a ID fabrication.
    const std::optional<uint64_t> hashedDisplayDetailsOpt =
            ftl::stable_hash(std::string_view(displayDetailsString.c_str(), 64));

    // Combine the hashes via bit-shifted XORs.
    const uint64_t id = (hashedDisplayDetailsOpt.value_or(0) << 17) ^
            (edid.hashedBlockZeroSerialNumberOpt.value_or(0) >> 11) ^
            (edid.hashedDescriptorBlockSerialNumberOpt.value_or(0) << 23);

    return PhysicalDisplayId::fromEdidHash(id);
}

} // namespace android
+8 −1
Original line number Diff line number Diff line
@@ -81,12 +81,17 @@ struct PhysicalDisplayId : DisplayId {
        return PhysicalDisplayId(id);
    }

    // Returns a stable ID based on EDID information.
    // Returns a stable ID based on EDID and port information.
    static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId,
                                                uint32_t modelHash) {
        return PhysicalDisplayId(FLAG_STABLE, port, manufacturerId, modelHash);
    }

    // Returns a stable and consistent ID based exclusively on EDID information.
    static constexpr PhysicalDisplayId fromEdidHash(uint64_t hashedEdid) {
        return PhysicalDisplayId(hashedEdid);
    }

    // Returns an unstable ID. If EDID is available using "fromEdid" is preferred.
    static constexpr PhysicalDisplayId fromPort(uint8_t port) {
        constexpr uint16_t kManufacturerId = 0;
@@ -103,6 +108,8 @@ private:
    // Flag indicating that the ID is stable across reboots.
    static constexpr uint64_t FLAG_STABLE = 1ULL << 62;

    using DisplayId::DisplayId;

    constexpr PhysicalDisplayId(uint64_t flags, uint8_t port, uint16_t manufacturerId,
                                uint32_t modelHash)
          : DisplayId(flags | (static_cast<uint64_t>(manufacturerId) << 40) |
+5 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ struct Edid {
    std::optional<uint64_t> hashedDescriptorBlockSerialNumberOpt;
    PnpId pnpId;
    uint32_t modelHash;
    // Up to 13 characters of ASCII text terminated by LF and padded with SP.
    std::string_view displayName;
    uint8_t manufactureOrModelYear;
    uint8_t manufactureWeek;
@@ -91,4 +92,8 @@ std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(

PhysicalDisplayId getVirtualDisplayId(uint32_t id);

// Generates a consistent, stable, and hashed display ID that is based on the
// display's parsed EDID fields.
PhysicalDisplayId generateEdidDisplayId(const Edid& edid);

} // namespace android
+16 −0
Original line number Diff line number Diff line
@@ -376,6 +376,22 @@ TEST(DisplayIdentificationTest, parseDisplayIdentificationData) {
    EXPECT_EQ(4633127902230889474, tertiaryInfo->id.value);
}

TEST(DisplayIdentificationTest, generateEdidDisplayId) {
    const auto firstExternalDisplayEdidOpt = parseEdid(getExternalEdid());
    ASSERT_TRUE(firstExternalDisplayEdidOpt);
    const PhysicalDisplayId firstExternalDisplayId =
            generateEdidDisplayId(firstExternalDisplayEdidOpt.value());

    const auto secondExternalDisplayEdidOpt = parseEdid(getExternalEedid());
    ASSERT_TRUE(secondExternalDisplayEdidOpt);
    const PhysicalDisplayId secondExternalDisplayId =
            generateEdidDisplayId(secondExternalDisplayEdidOpt.value());

    // Display IDs should be unique.
    EXPECT_EQ(4067182673952280501u, firstExternalDisplayId.value);
    EXPECT_EQ(14712168404707886855u, secondExternalDisplayId.value);
}

TEST(DisplayIdentificationTest, deviceProductInfo) {
    using ManufactureYear = DeviceProductInfo::ManufactureYear;
    using ManufactureWeekAndYear = DeviceProductInfo::ManufactureWeekAndYear;