SF: Temporarily expose primary display id

WM needs to know the address of the primary display in order to
consume ro.surface_flinger.primary_display_orientation correctly.
This path will be removed in the future once we support per
display install orientations.

Bug: 196167822
Test: check initial buffer transforms on displays with a different
install orientation

Merged-In: I2b0a92196a8a1f05f7d99b531775b9979f07af98
Change-Id: I2b0a92196a8a1f05f7d99b531775b9979f07af98
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 0d7795e..a82fc6f 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -291,6 +291,17 @@
         return {};
     }
 
+    status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId* displayId) const override {
+        Parcel data, reply;
+        SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
+        SAFE_PARCEL(remote()->transact, BnSurfaceComposer::GET_PRIMARY_PHYSICAL_DISPLAY_ID, data,
+                    &reply);
+        uint64_t rawId;
+        SAFE_PARCEL(reply.readUint64, &rawId);
+        *displayId = PhysicalDisplayId(rawId);
+        return NO_ERROR;
+    }
+
     sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -1713,6 +1724,16 @@
                            [](PhysicalDisplayId id) { return id.value; });
             return reply->writeUint64Vector(rawIds);
         }
+        case GET_PRIMARY_PHYSICAL_DISPLAY_ID: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            PhysicalDisplayId id;
+            status_t result = getPrimaryPhysicalDisplayId(&id);
+            if (result != NO_ERROR) {
+                ALOGE("getPrimaryPhysicalDisplayId: Failed to get id");
+                return result;
+            }
+            return reply->writeUint64(id.value);
+        }
         case ADD_REGION_SAMPLING_LISTENER: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             Rect samplingArea;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 96da8ef..1377284 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -913,6 +913,10 @@
     return ComposerService::getComposerService()->getPhysicalDisplayIds();
 }
 
+status_t SurfaceComposerClient::getPrimaryPhysicalDisplayId(PhysicalDisplayId* id) {
+    return ComposerService::getComposerService()->getPrimaryPhysicalDisplayId(id);
+}
+
 std::optional<PhysicalDisplayId> SurfaceComposerClient::getInternalDisplayId() {
     return ComposerService::getComposerService()->getInternalDisplayId();
 }
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 2a3f6a4..ef5353f 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -140,6 +140,8 @@
      */
     virtual std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const = 0;
 
+    virtual status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*) const = 0;
+
     // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
     std::optional<PhysicalDisplayId> getInternalDisplayId() const {
         const auto displayIds = getPhysicalDisplayIds();
@@ -624,6 +626,7 @@
         ON_PULL_ATOM,
         ADD_TUNNEL_MODE_ENABLED_LISTENER,
         REMOVE_TUNNEL_MODE_ENABLED_LISTENER,
+        GET_PRIMARY_PHYSICAL_DISPLAY_ID,
         // Always append new enum to the end.
     };
 
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index baa0567..4164ca3 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -307,6 +307,7 @@
 
     //! Get stable IDs for connected physical displays
     static std::vector<PhysicalDisplayId> getPhysicalDisplayIds();
+    static status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*);
     static std::optional<PhysicalDisplayId> getInternalDisplayId();
 
     //! Get token for a physical display given its stable ID
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 59b0c04..630dd17 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -694,6 +694,7 @@
             bool /*secure*/) override { return nullptr; }
     void destroyDisplay(const sp<IBinder>& /*display */) override {}
     std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override { return {}; }
+    status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*) const override { return NO_ERROR; }
     sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId) const override { return nullptr; }
     status_t setTransactionState(const FrameTimelineInfo& /*frameTimelineInfo*/,
                                  const Vector<ComposerState>& /*state*/,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 230810c..abc49bf 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -653,6 +653,17 @@
     return displayIds;
 }
 
+status_t SurfaceFlinger::getPrimaryPhysicalDisplayId(PhysicalDisplayId* id) const {
+    Mutex::Autolock lock(mStateLock);
+    const auto display = getInternalDisplayIdLocked();
+    if (!display) {
+        return NAME_NOT_FOUND;
+    }
+
+    *id = *display;
+    return NO_ERROR;
+}
+
 sp<IBinder> SurfaceFlinger::getPhysicalDisplayToken(PhysicalDisplayId displayId) const {
     Mutex::Autolock lock(mStateLock);
     return getPhysicalDisplayTokenLocked(displayId);
@@ -5238,6 +5249,7 @@
         case REMOVE_TUNNEL_MODE_ENABLED_LISTENER:
         case NOTIFY_POWER_BOOST:
         case SET_GLOBAL_SHADOW_SETTINGS:
+        case GET_PRIMARY_PHYSICAL_DISPLAY_ID:
         case ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN: {
             // ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN and OVERRIDE_HDR_TYPES are used by CTS tests,
             // which acquire the necessary permission dynamically. Don't use the permission cache
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 380f444..fa19b7f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -614,6 +614,7 @@
     sp<IBinder> createDisplay(const String8& displayName, bool secure) override;
     void destroyDisplay(const sp<IBinder>& displayToken) override;
     std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override;
+    status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*) const override EXCLUDES(mStateLock);
     sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override;
     status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo,
                                  const Vector<ComposerState>& state,
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.cpp b/services/surfaceflinger/SurfaceFlingerProperties.cpp
index 4a69c8f..e15eae8 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.cpp
+++ b/services/surfaceflinger/SurfaceFlingerProperties.cpp
@@ -34,6 +34,8 @@
 using android::hardware::graphics::common::V1_2::PixelFormat;
 using android::ui::DisplayPrimaries;
 
+// Keep logic in sync with WindowManagerService functions that query SurfaceFlinger properties.
+// Consider exposing properties via ISurfaceComposer instead.
 int64_t vsync_event_phase_offset_ns(int64_t defaultValue) {
     auto temp = SurfaceFlingerProperties::vsync_event_phase_offset_ns();
     if (temp.has_value()) {