summaryrefslogtreecommitdiff
path: root/libs/ui/DisplayIdentification.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ui/DisplayIdentification.cpp')
-rw-r--r--libs/ui/DisplayIdentification.cpp40
1 files changed, 37 insertions, 3 deletions
diff --git a/libs/ui/DisplayIdentification.cpp b/libs/ui/DisplayIdentification.cpp
index 8b13d78840..8d6f74b605 100644
--- a/libs/ui/DisplayIdentification.cpp
+++ b/libs/ui/DisplayIdentification.cpp
@@ -19,9 +19,12 @@
#include <algorithm>
#include <cctype>
+#include <cstdint>
#include <numeric>
#include <optional>
#include <span>
+#include <string>
+#include <string_view>
#include <ftl/hash.h>
#include <log/log.h>
@@ -194,6 +197,21 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
const uint16_t productId =
static_cast<uint16_t>(edid[kProductIdOffset] | (edid[kProductIdOffset + 1] << 8));
+ // Bytes 12-15: display serial number, in little-endian (LSB). This field is
+ // optional and its absence is marked by having all bytes set to 0x00.
+ // Values do not represent ASCII characters.
+ constexpr size_t kSerialNumberOffset = 12;
+ if (edid.size() < kSerialNumberOffset + sizeof(uint32_t)) {
+ ALOGE("Invalid EDID: block zero S/N is truncated.");
+ return {};
+ }
+ const uint32_t blockZeroSerialNumber = edid[kSerialNumberOffset] +
+ (edid[kSerialNumberOffset + 1] << 8) + (edid[kSerialNumberOffset + 2] << 16) +
+ (edid[kSerialNumberOffset + 3] << 24);
+ const auto hashedBlockZeroSNOpt = blockZeroSerialNumber == 0
+ ? std::nullopt
+ : ftl::stable_hash(std::string_view(std::to_string(blockZeroSerialNumber)));
+
constexpr size_t kManufactureWeekOffset = 16;
if (edid.size() < kManufactureWeekOffset + sizeof(uint8_t)) {
ALOGE("Invalid EDID: manufacture week is truncated.");
@@ -212,6 +230,15 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
ALOGW_IF(manufactureOrModelYear <= 0xf,
"Invalid EDID: model year or manufacture year cannot be in the range [0x0, 0xf].");
+ constexpr size_t kMaxHorizontalPhysicalSizeOffset = 21;
+ constexpr size_t kMaxVerticalPhysicalSizeOffset = 22;
+ if (edid.size() < kMaxVerticalPhysicalSizeOffset + sizeof(uint8_t)) {
+ ALOGE("Invalid EDID: display's physical size is truncated.");
+ return {};
+ }
+ ui::Size maxPhysicalSizeInCm(edid[kMaxHorizontalPhysicalSizeOffset],
+ edid[kMaxVerticalPhysicalSizeOffset]);
+
constexpr size_t kDescriptorOffset = 54;
if (edid.size() < kDescriptorOffset) {
ALOGE("Invalid EDID: descriptors are missing.");
@@ -222,7 +249,8 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
view = view.subspan(kDescriptorOffset);
std::string_view displayName;
- std::string_view serialNumber;
+ std::string_view descriptorBlockSerialNumber;
+ std::optional<uint64_t> hashedDescriptorBlockSNOpt = std::nullopt;
std::string_view asciiText;
ui::Size preferredDTDPixelSize;
ui::Size preferredDTDPhysicalSize;
@@ -247,7 +275,10 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
asciiText = parseEdidText(descriptor);
break;
case 0xff:
- serialNumber = parseEdidText(descriptor);
+ descriptorBlockSerialNumber = parseEdidText(descriptor);
+ hashedDescriptorBlockSNOpt = descriptorBlockSerialNumber.empty()
+ ? std::nullopt
+ : ftl::stable_hash(descriptorBlockSerialNumber);
break;
}
} else if (isDetailedTimingDescriptor(view)) {
@@ -288,7 +319,7 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
if (modelString.empty()) {
ALOGW("Invalid EDID: falling back to serial number due to missing display name.");
- modelString = serialNumber;
+ modelString = descriptorBlockSerialNumber;
}
if (modelString.empty()) {
ALOGW("Invalid EDID: falling back to ASCII text due to missing serial number.");
@@ -341,11 +372,14 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
return Edid{
.manufacturerId = manufacturerId,
.productId = productId,
+ .hashedBlockZeroSerialNumberOpt = hashedBlockZeroSNOpt,
+ .hashedDescriptorBlockSerialNumberOpt = hashedDescriptorBlockSNOpt,
.pnpId = *pnpId,
.modelHash = modelHash,
.displayName = displayName,
.manufactureOrModelYear = manufactureOrModelYear,
.manufactureWeek = manufactureWeek,
+ .physicalSizeInCm = maxPhysicalSizeInCm,
.cea861Block = cea861Block,
.preferredDetailedTimingDescriptor = preferredDetailedTimingDescriptor,
};