Remove internal display related methods

SurfaceFlinger and SurfaceComposerClient simply return the first
connected display as internal display, which is not really correct.
In particular,in the case of dual display for foldable devices, both
displays are marked as Internal determined by calling into HWC2
IComposerClient::getDisplayConnectionType().

Therefore, the concept of internal/external/primary displays is removed
from SurfaceFlinger, and the display manager is the better place to
handle the logics.

flatland is modified to take an extra argument to specify display id,
and error occurs if no display is specified in case of multi-display.

Bug: 241285477
Bug: 242763577
Bug: 74619554
Test: atest libgui_test libsurfaceflinger_unittest SurfaceFlinger_test
Change-Id: Ib6c7e502ef3269c2c60a4e5388e5ac75275f87ed
diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp
index 01f7d30..c163095 100644
--- a/cmds/flatland/GLHelper.cpp
+++ b/cmds/flatland/GLHelper.cpp
@@ -35,9 +35,12 @@
 GLHelper::~GLHelper() {
 }
 
-bool GLHelper::setUp(const ShaderDesc* shaderDescs, size_t numShaders) {
+bool GLHelper::setUp(const sp<IBinder>& displayToken, const ShaderDesc* shaderDescs,
+                     size_t numShaders) {
     bool result;
 
+    mDisplayToken = displayToken;
+
     mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     if (mDisplay == EGL_NO_DISPLAY) {
         fprintf(stderr, "eglGetDisplay error: %#x\n", eglGetError());
@@ -221,14 +224,8 @@
 }
 
 bool GLHelper::computeWindowScale(uint32_t w, uint32_t h, float* scale) {
-    const sp<IBinder> dpy = mSurfaceComposerClient->getInternalDisplayToken();
-    if (dpy == nullptr) {
-        fprintf(stderr, "SurfaceComposer::getInternalDisplayToken failed.\n");
-        return false;
-    }
-
     ui::DisplayMode mode;
-    status_t err = mSurfaceComposerClient->getActiveDisplayMode(dpy, &mode);
+    status_t err = mSurfaceComposerClient->getActiveDisplayMode(mDisplayToken, &mode);
     if (err != NO_ERROR) {
         fprintf(stderr, "SurfaceComposer::getActiveDisplayMode failed: %#x\n", err);
         return false;
diff --git a/cmds/flatland/GLHelper.h b/cmds/flatland/GLHelper.h
index d09463a..5194f50 100644
--- a/cmds/flatland/GLHelper.h
+++ b/cmds/flatland/GLHelper.h
@@ -44,7 +44,7 @@
 
     ~GLHelper();
 
-    bool setUp(const ShaderDesc* shaderDescs, size_t numShaders);
+    bool setUp(const sp<IBinder>& displayToken, const ShaderDesc* shaderDescs, size_t numShaders);
 
     void tearDown();
 
@@ -87,6 +87,8 @@
     size_t mNumShaders;
 
     GLuint mDitherTexture;
+
+    sp<IBinder> mDisplayToken;
 };
 
 } // namespace android
diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp
index 7ceb397..6d14d56 100644
--- a/cmds/flatland/Main.cpp
+++ b/cmds/flatland/Main.cpp
@@ -20,6 +20,7 @@
 #include <gui/SurfaceControl.h>
 #include <gui/GLConsumer.h>
 #include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
 #include <ui/Fence.h>
 #include <utils/Trace.h>
 
@@ -34,9 +35,10 @@
 
 using namespace ::android;
 
-static uint32_t g_SleepBetweenSamplesMs = 0;
-static bool     g_PresentToWindow       = false;
-static size_t   g_BenchmarkNameLen      = 0;
+static uint32_t    g_SleepBetweenSamplesMs = 0;
+static bool        g_PresentToWindow       = false;
+static size_t      g_BenchmarkNameLen      = 0;
+static sp<IBinder> g_DisplayToken          = nullptr;
 
 struct BenchmarkDesc {
     // The name of the test.
@@ -393,7 +395,7 @@
         uint32_t h = mDesc.runHeights[mInstance];
 
         mGLHelper = new GLHelper();
-        result = mGLHelper->setUp(shaders, NELEMS(shaders));
+        result = mGLHelper->setUp(g_DisplayToken, shaders, NELEMS(shaders));
         if (!result) {
             return false;
         }
@@ -718,13 +720,17 @@
 }
 
 // Print the command usage help to stderr.
-static void showHelp(const char *cmd) {
-    fprintf(stderr, "usage: %s [options]\n", cmd);
-    fprintf(stderr, "options include:\n"
-                    "  -s N            sleep for N ms between samples\n"
-                    "  -d              display the test frame to a window\n"
-                    "  --help          print this helpful message and exit\n"
-            );
+static void showHelp(const char* cmd) {
+  fprintf(stderr, "usage: %s [options]\n", cmd);
+  fprintf(
+      stderr,
+      "options include:\n"
+      "  -s N            sleep for N ms between samples\n"
+      "  -d              display the test frame to a window\n"
+      "  -i display-id   specify a display ID to use for multi-display device\n"
+      "                  see \"dumpsys SurfaceFlinger --display-id\" for valid "
+      "display IDs\n"
+      "  --help          print this helpful message and exit\n");
 }
 
 int main(int argc, char** argv) {
@@ -733,6 +739,14 @@
         exit(0);
     }
 
+    const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
+    if (ids.empty()) {
+        fprintf(stderr, "Failed to get ID for any displays.\n");
+        exit(3);
+    }
+
+    std::optional<PhysicalDisplayId> displayId;
+
     for (;;) {
         int ret;
         int option_index = 0;
@@ -741,7 +755,7 @@
             {     0,               0, 0,  0 }
         };
 
-        ret = getopt_long(argc, argv, "ds:",
+        ret = getopt_long(argc, argv, "ds:i:",
                           long_options, &option_index);
 
         if (ret < 0) {
@@ -757,6 +771,14 @@
                 g_SleepBetweenSamplesMs = atoi(optarg);
             break;
 
+            case 'i':
+                displayId = DisplayId::fromValue<PhysicalDisplayId>(atoll(optarg));
+                if (!displayId) {
+                    fprintf(stderr, "Invalid display ID: %s.\n", optarg);
+                    exit(4);
+                }
+            break;
+
             case 0:
                 if (strcmp(long_options[option_index].name, "help")) {
                     showHelp(argv[0]);
@@ -770,6 +792,22 @@
         }
     }
 
+    if (!displayId) { // no display id is specified
+        if (ids.size() == 1) {
+            displayId = ids.front();
+        } else {
+            fprintf(stderr, "Please specify a display ID for multi-display device.\n");
+            showHelp(argv[0]);
+            exit(5);
+        }
+    }
+
+    g_DisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
+    if (g_DisplayToken == nullptr) {
+        fprintf(stderr, "SurfaceComposer::getPhysicalDisplayToken failed.\n");
+        exit(6);
+    }
+
     g_BenchmarkNameLen = maxBenchmarkNameLen();
 
     printf(" cmdline:");
@@ -782,4 +820,6 @@
         fprintf(stderr, "exiting due to error.\n");
         return 1;
     }
+
+    return 0;
 }