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

Commit dc27ea37 authored by Gil Dekel's avatar Gil Dekel Committed by Android (Google) Code Review
Browse files

Merge changes Ic31c996e,Icb1ec5b7,I94ebda3f,I64abf8c7,I4aef05de, ... into main

* changes:
  HWComposer: Add reconnect status to DisplayIdentificationInfo
  SF: use a switch for events in configureLocked()
  HWComposer: Display ID conflict resolution logic
  DisplayIdentification: guard EDID IDs with stable_edid_ids()
  DualDisplayTransactionTest: init ID vars via getters
  FlagManager: Move mInstance to getMutableInstance
parents 4bc0370c 718012f2
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <string>
#include <string_view>

#include <common/FlagManager.h>
#include <ftl/concat.h>
#include <ftl/hash.h>
#include <log/log.h>
@@ -418,7 +419,9 @@ std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
        return {};
    }

    const auto displayId = PhysicalDisplayId::fromEdid(port, edid->manufacturerId, edid->modelHash);
    const auto displayId = FlagManager::getInstance().stable_edid_ids()
            ? generateEdidDisplayId(*edid)
            : PhysicalDisplayId::fromEdid(port, edid->manufacturerId, edid->modelHash);
    return DisplayIdentificationInfo{
            .id = displayId,
            .name = std::string(edid->displayName),
@@ -429,6 +432,16 @@ std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
    };
}

PhysicalDisplayId resolveDisplayIdCollision(PhysicalDisplayId id, uint8_t port) {
    const uint8_t lowByte = static_cast<uint8_t>(id.value) == port ? ~port : port;
    const uint64_t newIdValue = (id.value & ~0xFFULL) | lowByte;

    ALOGI("Display ID %" PRIu64 " --> resolved to %" PRIu64 " using %" PRIu8 " as suffix.",
          id.value, newIdValue, lowByte);

    return PhysicalDisplayId::fromValue(newIdValue);
}

PhysicalDisplayId getVirtualDisplayId(uint32_t id) {
    return PhysicalDisplayId::fromEdid(0, kVirtualEdidManufacturerId, id);
}
+10 −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;
@@ -92,6 +99,8 @@ std::optional<PnpId> getPnpId(uint16_t manufacturerId);
std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
        uint8_t port, const DisplayIdentificationData&, android::ScreenPartStatus screenPartStatus);

PhysicalDisplayId resolveDisplayIdCollision(PhysicalDisplayId id, uint8_t port);

PhysicalDisplayId getVirtualDisplayId(uint32_t id);

// Generates a consistent, stable, and hashed display ID that is based on the
+29 −1
Original line number Diff line number Diff line
@@ -234,6 +234,13 @@ void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, Physical
             "Attaching display %" PRIu64 " to an already active port %" PRIu8 ".", hwcDisplayId,
             port);

    if (FlagManager::getInstance().stable_edid_ids()) {
        LOG_ALWAYS_FATAL_IF(hasDisplayWithId(displayId),
                            "Cannot attach display to HAL display %" PRIu64
                            " with a duplicate display ID %" PRIu64 ".",
                            hwcDisplayId, displayId.value);
    }

    mPhysicalDisplayIdMap[hwcDisplayId] = displayId;

    if (!mPrimaryHwcDisplayId) {
@@ -1201,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;
@@ -1235,8 +1244,12 @@ std::optional<display::DisplayIdentificationInfo> HWComposer::onHotplugConnect(
        info = [this, hwcDisplayId, &port, &data, &screenPartStatus, hasDisplayIdentificationData] {
            const bool isPrimary = !mPrimaryHwcDisplayId;
            if (mHasMultiDisplaySupport) {
                if (const auto info =
                if (auto info =
                            display::parseDisplayIdentificationData(port, data, screenPartStatus)) {
                    if (FlagManager::getInstance().stable_edid_ids() &&
                        hasDisplayWithId(info->id)) {
                        info->id = display::resolveDisplayIdCollision(info->id, info->port);
                    }
                    return *info;
                }
                ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
@@ -1255,6 +1268,15 @@ std::optional<display::DisplayIdentificationInfo> HWComposer::onHotplugConnect(
            };
        }();

        // Fail the hotplug if the display ID conflict could not be resolved to avoid display
        // mixups.
        if (FlagManager::getInstance().stable_edid_ids() && hasDisplayWithId(info->id)) {
            ALOGE("Ignoring connection of display %" PRIu64
                  ". Failed to resolve Display ID collision for duplicate display ID %" PRIu64 ".",
                  hwcDisplayId, info->id.value);
            return {};
        }

        mComposer->onHotplugConnect(hwcDisplayId);
    }

@@ -1369,6 +1391,12 @@ void HWComposer::loadLayerMetadataSupport() {
    }
}

bool HWComposer::hasDisplayWithId(PhysicalDisplayId displayId) const {
    return ftl::find_if(mPhysicalDisplayIdMap,
                        [displayId](const auto& pair) { return pair.second == displayId; })
            .has_value();
}

} // namespace impl
} // namespace android

+1 −0
Original line number Diff line number Diff line
@@ -592,6 +592,7 @@ private:
    void loadLayerMetadataSupport();
    void loadOverlayProperties();
    void loadHdrConversionCapabilities();
    bool hasDisplayWithId(PhysicalDisplayId displayId) const;

    std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
    ui::PhysicalDisplaySet<uint8_t> mActivePorts;
+14 −10
Original line number Diff line number Diff line
@@ -3758,13 +3758,16 @@ bool SurfaceFlinger::configureLocked() {
    }

    for (const auto [hwcDisplayId, event] : events) {
        if (auto info = getHwComposer().onHotplug(hwcDisplayId, event)) {
        auto info = getHwComposer().onHotplug(hwcDisplayId, event);
        if (!info) {
            continue;
        }

        const auto displayId = info->id;
            const ftl::Concat displayString("display ", displayId.value, "(HAL ID ", hwcDisplayId,
                                            ')');
            // TODO: b/393126541 - replace if with switch as all cases are handled.
            if (event == HWComposer::HotplugEvent::Connected ||
                event == HWComposer::HotplugEvent::LinkUnstable) {
        const ftl::Concat displayString("display ", displayId.value, "(HAL ID ", hwcDisplayId, ')');
        switch (event) {
            case HWComposer::HotplugEvent::Connected:
            case HWComposer::HotplugEvent::LinkUnstable: {
                const auto activeModeIdOpt =
                        processHotplugConnect(displayId, hwcDisplayId, std::move(*info),
                                              displayString.c_str(), event);
@@ -3793,12 +3796,13 @@ bool SurfaceFlinger::configureLocked() {
                LOG_ALWAYS_FATAL_IF(!snapshotOpt);

                mDisplayModeController.registerDisplay(*snapshotOpt, *activeModeIdOpt, config);
            } else { // event == HWComposer::HotplugEvent::Disconnected
                break;
            }
            case HWComposer::HotplugEvent::Disconnected:
                // Unregister before destroying the DisplaySnapshot below.
                mDisplayModeController.unregisterDisplay(displayId);

                processHotplugDisconnect(displayId, displayString.c_str());
            }
                break;
        }
    }

Loading