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

Commit 913cc130 authored by mamik's avatar mamik
Browse files

EDID support for external display hotplug

The hardware_composer caches the edid when a new hotplug event fires
(connected and disconnected). The display services uses this cached edid
when the edid is requested.

Bug: 141007548
Test: Manual, ran on mtp device with wave optics plugged in and
unplugged and verified edid with: "adb shell dumpsys SurfaceFlinger --display-id"

Change-Id: I4556e1d8a3f8677b1d9301d9afbc40d514c86e27
parent 5dd64b1e
Loading
Loading
Loading
Loading
+9 −17
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
#include <private/dvr/trusted_uids.h>
#include <private/dvr/types.h>

#include "DisplayHardware/DisplayIdentification.h"

using android::dvr::display::DisplayProtocol;
using android::pdx::Channel;
using android::pdx::ErrorStatus;
@@ -44,19 +46,6 @@ DisplayService::DisplayService(Hwc2::Composer* hidl,
           Endpoint::Create(display::DisplayProtocol::kClientPath)) {
    hardware_composer_.Initialize(
        hidl, primary_display_id, request_display_callback);

    uint8_t port;
    const auto error = hidl->getDisplayIdentificationData(
        primary_display_id, &display_identification_port_,
        &display_identification_data_);
    if (error != android::hardware::graphics::composer::V2_1::Error::NONE) {
      if (error !=
          android::hardware::graphics::composer::V2_1::Error::UNSUPPORTED) {
        ALOGI("DisplayService: identification data error\n");
      } else {
        ALOGI("DisplayService: identification data unsupported\n");
      }
    }
}

bool DisplayService::IsInitialized() const {
@@ -212,6 +201,7 @@ Status<display::Metrics> DisplayService::OnGetMetrics(
pdx::Status<std::string> DisplayService::OnGetConfigurationData(
    pdx::Message& /*message*/, display::ConfigFileType config_type) {
  std::string property_name;
  DisplayIdentificationData display_identification_data;
  switch (config_type) {
    case display::ConfigFileType::kLensMetrics:
      property_name = kDvrLensMetricsProperty;
@@ -223,11 +213,13 @@ pdx::Status<std::string> DisplayService::OnGetConfigurationData(
      property_name = kDvrDeviceConfigProperty;
      break;
    case display::ConfigFileType::kDeviceEdid:
      if (display_identification_data_.size() == 0) {
      display_identification_data =
          hardware_composer_.GetCurrentDisplayIdentificationData();
      if (display_identification_data.size() == 0) {
        return ErrorStatus(ENOENT);
      }
      return std::string(display_identification_data_.begin(),
                         display_identification_data_.end());
      return std::string(display_identification_data.begin(),
                         display_identification_data.end());
    default:
      return ErrorStatus(EINVAL);
  }
@@ -246,7 +238,7 @@ pdx::Status<std::string> DisplayService::OnGetConfigurationData(

pdx::Status<uint8_t> DisplayService::OnGetDisplayIdentificationPort(
    pdx::Message& /*message*/) {
  return display_identification_port_;
  return hardware_composer_.GetCurrentDisplayPort();
}

// Creates a new DisplaySurface and associates it with this channel. This may
+0 −5
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@
#include "epoll_event_dispatcher.h"
#include "hardware_composer.h"

#include "DisplayHardware/DisplayIdentification.h"

namespace android {
namespace dvr {

@@ -120,9 +118,6 @@ class DisplayService : public pdx::ServiceBase<DisplayService> {

  DisplayService(const DisplayService&) = delete;
  void operator=(const DisplayService&) = delete;

  DisplayIdentificationData display_identification_data_;
  uint8_t display_identification_port_;
};

}  // namespace dvr
+19 −0
Original line number Diff line number Diff line
@@ -137,6 +137,20 @@ HardwareComposer::~HardwareComposer(void) {
  composer_callback_->SetVsyncService(nullptr);
}

void HardwareComposer::UpdateEdidData(Hwc2::Composer* composer,
                                      hwc2_display_t hw_id) {
  const auto error = composer->getDisplayIdentificationData(
      hw_id, &display_port_, &display_identification_data_);
  if (error != android::hardware::graphics::composer::V2_1::Error::NONE) {
    if (error !=
        android::hardware::graphics::composer::V2_1::Error::UNSUPPORTED) {
      ALOGI("hardware_composer: identification data error\n");
    } else {
      ALOGI("hardware_composer: identification data unsupported\n");
    }
  }
}

bool HardwareComposer::Initialize(
    Hwc2::Composer* composer, hwc2_display_t primary_display_id,
    RequestDisplayCallback request_display_callback) {
@@ -164,6 +178,8 @@ bool HardwareComposer::Initialize(
      "HardwareComposer: Failed to create interrupt event fd : %s",
      strerror(errno));

  UpdateEdidData(composer, primary_display_id);

  post_thread_ = std::thread(&HardwareComposer::PostThread, this);

  initialized_ = true;
@@ -988,6 +1004,9 @@ bool HardwareComposer::UpdateTargetDisplay() {
      EnableDisplay(*external_display_, false);
    }

    // Update the cached edid data for the current display.
    UpdateEdidData(composer_.get(), target_display_->id);

    // Turn the new target display on.
    EnableDisplay(*target_display_, true);

+14 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <private/dvr/shared_buffer_helpers.h>
#include <private/dvr/vsync_service.h>

#include "DisplayHardware/DisplayIdentification.h"
#include "acquired_buffer.h"
#include "display_surface.h"

@@ -334,6 +335,14 @@ class HardwareComposer {
  int OnNewGlobalBuffer(DvrGlobalBufferKey key, IonBuffer& ion_buffer);
  void OnDeletedGlobalBuffer(DvrGlobalBufferKey key);

  // Gets the edid data for the current active display (internal or external)
  DisplayIdentificationData GetCurrentDisplayIdentificationData() {
    return display_identification_data_;
  }

  // Gets the edid port for the current active display (internal or external)
  uint8_t GetCurrentDisplayPort() { return display_port_; }

 private:
  DisplayParams GetDisplayParams(Hwc2::Composer* composer,
      hwc2_display_t display, bool is_primary);
@@ -544,6 +553,11 @@ class HardwareComposer {
  bool vsync_trace_parity_ = false;
  sp<VsyncService> vsync_service_;

  // Edid section.
  void UpdateEdidData(Hwc2::Composer* composer, hwc2_display_t hw_id);
  DisplayIdentificationData display_identification_data_;
  uint8_t display_port_;

  static constexpr int kPostThreadInterrupted = 1;

  HardwareComposer(const HardwareComposer&) = delete;