screencap: Allow virtual display ID in -d switch

Ibe3679d810602456205e157fe2cb8cc510062215 restricted the argument to
PhysicalDisplayId, which prevents capture of virtual displays.

Fixes: 280785757
Test: screencap -d <id>
Change-Id: I41a8d1adaa51c6804c03f1b3084ac04ff6b4f1fa
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index d7222d2..863efff 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -30,6 +30,8 @@
 
 #include <binder/ProcessState.h>
 
+#include <ftl/concat.h>
+#include <ftl/optional.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/SurfaceComposerClient.h>
 #include <gui/SyncScreenCaptureListener.h>
@@ -45,14 +47,7 @@
 #define COLORSPACE_SRGB       1
 #define COLORSPACE_DISPLAY_P3 2
 
-static void usage(const char* pname, std::optional<PhysicalDisplayId> displayId)
-{
-    std::string defaultDisplayStr = "";
-    if (!displayId) {
-        defaultDisplayStr = "";
-    } else {
-        defaultDisplayStr = " (default: " + to_string(*displayId) + ")";
-    }
+void usage(const char* pname, ftl::Optional<DisplayId> displayIdOpt) {
     fprintf(stderr,
             "usage: %s [-hp] [-d display-id] [FILENAME]\n"
             "   -h: this message\n"
@@ -61,7 +56,13 @@
             "       see \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n"
             "If FILENAME ends with .png it will be saved as a png.\n"
             "If FILENAME is not given, the results will be printed to stdout.\n",
-            pname, defaultDisplayStr.c_str());
+            pname,
+            displayIdOpt
+                    .transform([](DisplayId id) {
+                        return std::string(ftl::Concat(" (default: ", id.value, ')').str());
+                    })
+                    .value_or(std::string())
+                    .c_str());
 }
 
 static int32_t flinger2bitmapFormat(PixelFormat f)
@@ -132,7 +133,7 @@
         fprintf(stderr, "Failed to get ID for any displays.\n");
         return 1;
     }
-    std::optional<PhysicalDisplayId> displayId;
+    std::optional<DisplayId> displayIdOpt;
     const char* pname = argv[0];
     bool png = false;
     int c;
@@ -142,8 +143,8 @@
                 png = true;
                 break;
             case 'd':
-                displayId = DisplayId::fromValue<PhysicalDisplayId>(atoll(optarg));
-                if (!displayId) {
+                displayIdOpt = DisplayId::fromValue(atoll(optarg));
+                if (!displayIdOpt) {
                     fprintf(stderr, "Invalid display ID: %s\n", optarg);
                     return 1;
                 }
@@ -151,15 +152,15 @@
             case '?':
             case 'h':
                 if (ids.size() == 1) {
-                    displayId = ids.front();
-                } 
-                usage(pname, displayId);
+                    displayIdOpt = ids.front();
+                }
+                usage(pname, displayIdOpt);
                 return 1;
         }
     }
 
-    if (!displayId) { // no diplsay id is specified
-        displayId = ids.front();
+    if (!displayIdOpt) {
+        displayIdOpt = ids.front();
         if (ids.size() > 1) {
             fprintf(stderr,
                     "[Warning] Multiple displays were found, but no display id was specified! "
@@ -191,7 +192,7 @@
     }
 
     if (fd == -1) {
-        usage(pname, displayId);
+        usage(pname, displayIdOpt);
         return 1;
     }
 
@@ -208,7 +209,7 @@
     ProcessState::self()->startThreadPool();
 
     sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
-    status_t result = ScreenshotClient::captureDisplay(*displayId, captureListener);
+    status_t result = ScreenshotClient::captureDisplay(*displayIdOpt, captureListener);
     if (result != NO_ERROR) {
         close(fd);
         return 1;