drm_hwcomposer: Implement getDisplayPhysicalOrientation()

Implement ComposerClient::getDisplayPhysicalOrientation() by querying
the DRM display panel orientation property and translating the result to
the correct common::Transform enum value.

The result is used by SurfaceFlinger to correctly rotate the image
before displaying it to the user.

Signed-off-by: Tim Van Patten <timvp@google.com>
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 7f65e65..6797c56 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -24,10 +24,15 @@
 #include "backend/Backend.h"
 #include "backend/BackendManager.h"
 #include "bufferinfo/BufferInfoGetter.h"
+#include "compositor/DisplayInfo.h"
+#include "drm/DrmConnector.h"
+#include "drm/DrmDisplayPipeline.h"
 #include "drm/DrmHwc.h"
 #include "utils/log.h"
 #include "utils/properties.h"
 
+using ::android::DrmDisplayPipeline;
+
 namespace android {
 
 std::string HwcDisplay::DumpDelta(HwcDisplay::Stats delta) {
@@ -196,6 +201,23 @@
   return HWC2::Error::None;
 }
 
+std::optional<PanelOrientation> HwcDisplay::getDisplayPhysicalOrientation() {
+  if (IsInHeadlessMode()) {
+    // The pipeline can be nullptr in headless mode, so return the default
+    // "normal" mode.
+    return PanelOrientation::kModePanelOrientationNormal;
+  }
+
+  DrmDisplayPipeline &pipeline = GetPipe();
+  if (pipeline.connector == nullptr || pipeline.connector->Get() == nullptr) {
+    ALOGW(
+        "No display pipeline present to query the panel orientation property.");
+    return {};
+  }
+
+  return pipeline.connector->Get()->GetPanelOrientation();
+}
+
 HWC2::Error HwcDisplay::ChosePreferredConfig() {
   HWC2::Error err{};
   if (type_ == HWC2::DisplayType::Virtual) {