Skip to content

Commit 846a737

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "SF: Add EDID-ID Fabrication Logic" into main
2 parents e17fc7a + 0bf26cd commit 846a737

4 files changed

Lines changed: 53 additions & 1 deletion

File tree

libs/ui/DisplayIdentification.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <string>
2727
#include <string_view>
2828

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

427+
PhysicalDisplayId generateEdidDisplayId(const Edid& edid) {
428+
const ftl::Concat displayDetailsString{edid.manufacturerId,
429+
edid.productId,
430+
ftl::truncated<13>(edid.displayName),
431+
edid.manufactureWeek,
432+
edid.manufactureOrModelYear,
433+
edid.physicalSizeInCm.getWidth(),
434+
edid.physicalSizeInCm.getHeight()};
435+
436+
// String has to be cropped to 64 characters (at most) for ftl::stable_hash.
437+
// This is fine as the accuracy or completeness of the above fields is not
438+
// critical for a ID fabrication.
439+
const std::optional<uint64_t> hashedDisplayDetailsOpt =
440+
ftl::stable_hash(std::string_view(displayDetailsString.c_str(), 64));
441+
442+
// Combine the hashes via bit-shifted XORs.
443+
const uint64_t id = (hashedDisplayDetailsOpt.value_or(0) << 17) ^
444+
(edid.hashedBlockZeroSerialNumberOpt.value_or(0) >> 11) ^
445+
(edid.hashedDescriptorBlockSerialNumberOpt.value_or(0) << 23);
446+
447+
return PhysicalDisplayId::fromEdidHash(id);
448+
}
449+
426450
} // namespace android

libs/ui/include/ui/DisplayId.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,17 @@ struct PhysicalDisplayId : DisplayId {
8181
return PhysicalDisplayId(id);
8282
}
8383

84-
// Returns a stable ID based on EDID information.
84+
// Returns a stable ID based on EDID and port information.
8585
static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId,
8686
uint32_t modelHash) {
8787
return PhysicalDisplayId(FLAG_STABLE, port, manufacturerId, modelHash);
8888
}
8989

90+
// Returns a stable and consistent ID based exclusively on EDID information.
91+
static constexpr PhysicalDisplayId fromEdidHash(uint64_t hashedEdid) {
92+
return PhysicalDisplayId(hashedEdid);
93+
}
94+
9095
// Returns an unstable ID. If EDID is available using "fromEdid" is preferred.
9196
static constexpr PhysicalDisplayId fromPort(uint8_t port) {
9297
constexpr uint16_t kManufacturerId = 0;
@@ -103,6 +108,8 @@ struct PhysicalDisplayId : DisplayId {
103108
// Flag indicating that the ID is stable across reboots.
104109
static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
105110

111+
using DisplayId::DisplayId;
112+
106113
constexpr PhysicalDisplayId(uint64_t flags, uint8_t port, uint16_t manufacturerId,
107114
uint32_t modelHash)
108115
: DisplayId(flags | (static_cast<uint64_t>(manufacturerId) << 40) |

libs/ui/include/ui/DisplayIdentification.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct Edid {
7474
std::optional<uint64_t> hashedDescriptorBlockSerialNumberOpt;
7575
PnpId pnpId;
7676
uint32_t modelHash;
77+
// Up to 13 characters of ASCII text terminated by LF and padded with SP.
7778
std::string_view displayName;
7879
uint8_t manufactureOrModelYear;
7980
uint8_t manufactureWeek;
@@ -91,4 +92,8 @@ std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
9192

9293
PhysicalDisplayId getVirtualDisplayId(uint32_t id);
9394

95+
// Generates a consistent, stable, and hashed display ID that is based on the
96+
// display's parsed EDID fields.
97+
PhysicalDisplayId generateEdidDisplayId(const Edid& edid);
98+
9499
} // namespace android

libs/ui/tests/DisplayIdentification_test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,22 @@ TEST(DisplayIdentificationTest, parseDisplayIdentificationData) {
376376
EXPECT_EQ(4633127902230889474, tertiaryInfo->id.value);
377377
}
378378

379+
TEST(DisplayIdentificationTest, generateEdidDisplayId) {
380+
const auto firstExternalDisplayEdidOpt = parseEdid(getExternalEdid());
381+
ASSERT_TRUE(firstExternalDisplayEdidOpt);
382+
const PhysicalDisplayId firstExternalDisplayId =
383+
generateEdidDisplayId(firstExternalDisplayEdidOpt.value());
384+
385+
const auto secondExternalDisplayEdidOpt = parseEdid(getExternalEedid());
386+
ASSERT_TRUE(secondExternalDisplayEdidOpt);
387+
const PhysicalDisplayId secondExternalDisplayId =
388+
generateEdidDisplayId(secondExternalDisplayEdidOpt.value());
389+
390+
// Display IDs should be unique.
391+
EXPECT_EQ(4067182673952280501u, firstExternalDisplayId.value);
392+
EXPECT_EQ(14712168404707886855u, secondExternalDisplayId.value);
393+
}
394+
379395
TEST(DisplayIdentificationTest, deviceProductInfo) {
380396
using ManufactureYear = DeviceProductInfo::ManufactureYear;
381397
using ManufactureWeekAndYear = DeviceProductInfo::ManufactureWeekAndYear;

0 commit comments

Comments
 (0)