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

Commit 652f5c10 authored by Gil Dekel's avatar Gil Dekel
Browse files

DisplayIdentification: Parse EDID structure version

Parse and serve the EDID's structure version via DeviceProductInfo in
SF. The EDID structure version is a required field.

Flag: com.android.graphics.surfaceflinger.flags.parse_edid_version_and_input_type
Bug: 420767380
Bug: 426524259
Test: DisplayIdentificationTest#deviceProductInfoWithEdidStructureMetadataAndVideoInputType
Change-Id: Icb2ce79788fa88b0f5b9d8797383fa31af27b3b8
parent 47acdca3
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -43,6 +43,12 @@ parcelable DeviceProductInfo {
        ManufactureWeekAndYear manufactureWeekAndYear;
    }

    parcelable EdidStructureMetadata {
        // The EDID structure version number and revision number fields (required).
        int version;
        int revision;
    }

    // Display name.
    @utf8InCpp String name;

@@ -54,5 +60,8 @@ parcelable DeviceProductInfo {

    ManufactureOrModelDate manufactureOrModelDate;

    // General EDID structure metadata.
    EdidStructureMetadata edidStructureMetadata;

    byte[] relativeAddress;
}
+9 −1
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@

#include <array>
#include <cstdint>
#include <optional>
#include <string>
#include <type_traits>
#include <variant>
@@ -44,6 +43,12 @@ struct DeviceProductInfo {
        uint8_t week;
    };

    struct EdidStructureMetadata {
        // The EDID structure version number and revision number fields (required).
        uint8_t version;
        uint8_t revision;
    };

    // Display name.
    std::string name;

@@ -57,6 +62,9 @@ struct DeviceProductInfo {
    static_assert(std::is_trivially_copyable_v<ManufactureOrModelDate>);
    ManufactureOrModelDate manufactureOrModelDate;

    // General EDID structure metadata.
    EdidStructureMetadata edidStructureMetadata;

    // Relative address in the display network. Empty vector indicates that the
    // address is unavailable.
    // For example, for HDMI connected device this will be the physical address.
+16 −0
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ char getPnpLetter(uint16_t id) {

DeviceProductInfo buildDeviceProductInfo(const Edid& edid) {
    DeviceProductInfo info;
    info.edidStructureMetadata = {.version = edid.edidStructureVersion,
                                  .revision = edid.edidStructureRevision};
    info.name.assign(edid.displayName);
    info.productId = std::to_string(edid.productId);
    info.manufacturerPnpId = edid.pnpId;
@@ -234,6 +236,18 @@ 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].");

    uint8_t edidStructureVersion = 0;
    uint8_t edidStructureRevision = 0;
    if (FlagManager::getInstance().parse_edid_version_and_input_type()) {
        constexpr uint8_t kEdidStructureVersionOffset = 18;
        if (edid.size() < kEdidStructureVersionOffset + sizeof(uint16_t)) {
            ALOGE("Invalid EDID: EDID structure version is truncated.");
            return {};
        }
        edidStructureVersion = edid[kEdidStructureVersionOffset];
        edidStructureRevision = edid[kEdidStructureVersionOffset + 1];
    }

    constexpr size_t kMaxHorizontalPhysicalSizeOffset = 21;
    constexpr size_t kMaxVerticalPhysicalSizeOffset = 22;
    if (edid.size() < kMaxVerticalPhysicalSizeOffset + sizeof(uint8_t)) {
@@ -388,6 +402,8 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
            .displayName = displayName,
            .manufactureOrModelYear = manufactureOrModelYear,
            .manufactureWeek = manufactureWeek,
            .edidStructureVersion = edidStructureVersion,
            .edidStructureRevision = edidStructureRevision,
            .physicalSizeInCm = maxPhysicalSizeInCm,
            .cea861Block = cea861Block,
            .preferredDetailedTimingDescriptor = preferredDetailedTimingDescriptor,
+2 −0
Original line number Diff line number Diff line
@@ -87,6 +87,8 @@ struct Edid {
    std::string_view displayName;
    uint8_t manufactureOrModelYear;
    uint8_t manufactureWeek;
    uint8_t edidStructureVersion;
    uint8_t edidStructureRevision;
    ui::Size physicalSizeInCm;
    std::optional<Cea861ExtensionBlock> cea861Block;
    std::optional<DetailedTimingDescriptor> preferredDetailedTimingDescriptor;
+71 −0
Original line number Diff line number Diff line
@@ -20,12 +20,14 @@

#include <string_view>

#include <common/test/FlagUtils.h>
#include <ftl/hash.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <ui/ScreenPartStatus.h>

#include "Display/DisplayIdentification.h"
#include "com_android_graphics_surfaceflinger_flags.h"

using ::testing::ElementsAre;

@@ -553,6 +555,75 @@ TEST(DisplayIdentificationTest, deviceProductInfo) {
    }
}

// This test can be folded into DisplayIdentificationTest#deviceProductInfo once
// the flag is removed.
TEST(DisplayIdentificationTest, deviceProductInfoWithEdidStructureMetadataAndVideoInputType) {
    SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::
                              parse_edid_version_and_input_type,
                      true);

    {
        const auto displayIdInfo =
                parseDisplayIdentificationData(0, getInternalEdid(),
                                               android::ScreenPartStatus::UNSUPPORTED);
        ASSERT_TRUE(displayIdInfo);
        ASSERT_TRUE(displayIdInfo->deviceProductInfo);
        const auto& info = *displayIdInfo->deviceProductInfo;
        EXPECT_EQ(1, info.edidStructureMetadata.version);
        EXPECT_EQ(3, info.edidStructureMetadata.revision);
    }
    {
        const auto displayIdInfo =
                parseDisplayIdentificationData(0, getExternalEdid(),
                                               android::ScreenPartStatus::UNSUPPORTED);
        ASSERT_TRUE(displayIdInfo);
        ASSERT_TRUE(displayIdInfo->deviceProductInfo);
        const auto& info = *displayIdInfo->deviceProductInfo;
        EXPECT_EQ(1, info.edidStructureMetadata.version);
        EXPECT_EQ(4, info.edidStructureMetadata.revision);
    }
    {
        const auto displayIdInfo =
                parseDisplayIdentificationData(0, getExternalEedid(),
                                               android::ScreenPartStatus::UNSUPPORTED);
        ASSERT_TRUE(displayIdInfo);
        ASSERT_TRUE(displayIdInfo->deviceProductInfo);
        const auto& info = *displayIdInfo->deviceProductInfo;
        EXPECT_EQ(1, info.edidStructureMetadata.version);
        EXPECT_EQ(3, info.edidStructureMetadata.revision);
    }
    {
        const auto displayIdInfo =
                parseDisplayIdentificationData(0, getPanasonicTvEdid(),
                                               android::ScreenPartStatus::UNSUPPORTED);
        ASSERT_TRUE(displayIdInfo);
        ASSERT_TRUE(displayIdInfo->deviceProductInfo);
        const auto& info = *displayIdInfo->deviceProductInfo;
        EXPECT_EQ(1, info.edidStructureMetadata.version);
        EXPECT_EQ(3, info.edidStructureMetadata.revision);
    }
    {
        const auto displayIdInfo =
                parseDisplayIdentificationData(0, getHisenseTvEdid(),
                                               android::ScreenPartStatus::UNSUPPORTED);
        ASSERT_TRUE(displayIdInfo);
        ASSERT_TRUE(displayIdInfo->deviceProductInfo);
        const auto& info = *displayIdInfo->deviceProductInfo;
        EXPECT_EQ(1, info.edidStructureMetadata.version);
        EXPECT_EQ(3, info.edidStructureMetadata.revision);
    }
    {
        const auto displayIdInfo =
                parseDisplayIdentificationData(0, getCtlDisplayEdid(),
                                               android::ScreenPartStatus::UNSUPPORTED);
        ASSERT_TRUE(displayIdInfo);
        ASSERT_TRUE(displayIdInfo->deviceProductInfo);
        const auto& info = *displayIdInfo->deviceProductInfo;
        EXPECT_EQ(1, info.edidStructureMetadata.version);
        EXPECT_EQ(4, info.edidStructureMetadata.revision);
    }
}

} // namespace android::display

// TODO(b/129481165): remove the #pragma below and fix conversion issues