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

Commit 718012f2 authored by Gil Dekel's avatar Gil Dekel
Browse files

HWComposer: Add reconnect status to DisplayIdentificationInfo

A display reconnect is a special case event in which the only available
display needs to be swapped out without being disconnected. Such cases
include (but are not limited to) ATV and headless AL in the near future.

Currently, the only way to detect a reconnect is by checking whether or
not a display is already available in the list of physical displays in
SF. This is not a good representation as the existence of a
display with a newly fabricated ID could indicate an error or a bug, and
so it is important to introduce another way to identify a display
reconnect at the time of a physical display creation.

This CL introduces a signal in DisplayIdentificationInfo to notify SF
when an incoming display is in fact reconnected instead of purely
connected.

Flag: EXEMPT refactor
Bug: 420970122
Test: HWComposerTest
Change-Id: Ic31c996e5ff1caff2f8a3ab931dffb33a26f99d4
parent 6d0ae807
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

#pragma once

#include <array>
#include <cstdint>
#include <optional>
#include <string>
@@ -35,6 +34,13 @@ namespace android::display {

using DisplayIdentificationData = std::vector<uint8_t>;

enum class HotplugStatus {
    Connected,
    // This is a special workaround for the lack of headless mode. If a display is in this status,
    // the display modes are reloaded.
    Reconnected
};

struct DetailedTimingDescriptor {
    ui::Size pixelSizeCount;
    ui::Size physicalSizeInMm;
@@ -44,6 +50,7 @@ struct DisplayIdentificationInfo {
    PhysicalDisplayId id;
    std::string name;
    uint8_t port;
    HotplugStatus hotplugStatus = HotplugStatus::Connected;
    std::optional<DeviceProductInfo> deviceProductInfo;
    std::optional<DetailedTimingDescriptor> preferredDetailedTimingDescriptor;
    ScreenPartStatus screenPartStatus;
+2 −0
Original line number Diff line number Diff line
@@ -1208,6 +1208,8 @@ std::optional<display::DisplayIdentificationInfo> HWComposer::onHotplugConnect(
    if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
        info = display::DisplayIdentificationInfo{.id = *displayId,
                                                  .name = std::string(),
                                                  .hotplugStatus =
                                                          display::HotplugStatus::Reconnected,
                                                  .deviceProductInfo = std::nullopt};
        if (mUpdateDeviceProductInfoOnHotplugReconnect) {
            uint8_t port;
+19 −0
Original line number Diff line number Diff line
@@ -477,6 +477,25 @@ TEST_F(HWComposerTest, onVsyncInvalid) {
    EXPECT_FALSE(displayIdOpt);
}

TEST_F(HWComposerTest, propagateHotplugReconnectStatus) {
    constexpr hal::HWDisplayId kHwcDisplayId = 1;
    constexpr uint8_t kPort = 0;
    expectHotplugConnect(kHwcDisplayId, kPort, getExternalEdid());

    const auto info1 = mHwc.onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected);
    ASSERT_TRUE(info1);
    EXPECT_EQ(display::HotplugStatus::Connected, info1->hotplugStatus);

    // Emit another hotplug event on the same display, but with a different EDID. This should
    // trigger a hotplug reconnect. Display identification data should not be fetched.
    EXPECT_CALL(*mHal, getDisplayIdentificationData(kHwcDisplayId, _, _, _)).Times(0);
    const auto info2 = mHwc.onHotplug(kHwcDisplayId, HWComposer::HotplugEvent::Connected);
    ASSERT_TRUE(info2);

    EXPECT_EQ(display::HotplugStatus::Reconnected, info2->hotplugStatus);
    EXPECT_EQ(info1->id, info2->id);
}

TEST_F(HWComposerTest, displayIdConflictResolution) {
    // Two different displays (connected to two different ports) produce the same EDID,
    // which will result in the same EDID-based display ID.