From 597703b62e05faea3c556565e0add4cff6bb54e6 Mon Sep 17 00:00:00 2001 From: SeungHoon Han Date: Wed, 9 Nov 2022 13:42:56 +0900 Subject: [PATCH] Fix DisplayInfo parsing for Android Q The DisplayInfo dump format has slightly changed in AOSP: PR #3573 Ref #3416 Signed-off-by: Romain Vimont --- .../scrcpy/wrappers/DisplayManager.java | 2 +- .../genymobile/scrcpy/CommandParserTest.java | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/wrappers/DisplayManager.java b/server/src/main/java/com/genymobile/scrcpy/wrappers/DisplayManager.java index bf172126..17b9ae4d 100644 --- a/server/src/main/java/com/genymobile/scrcpy/wrappers/DisplayManager.java +++ b/server/src/main/java/com/genymobile/scrcpy/wrappers/DisplayManager.java @@ -21,7 +21,7 @@ public final class DisplayManager { // public to call it from unit tests public static DisplayInfo parseDisplayInfo(String dumpsysDisplayOutput, int displayId) { Pattern regex = Pattern.compile( - "^ mOverrideDisplayInfo=DisplayInfo\\{\".*?\", displayId " + displayId + ".*?(, FLAG_.*)?, real ([0-9]+) x ([0-9]+).*?, " + "^ mOverrideDisplayInfo=DisplayInfo\\{\".*?, displayId " + displayId + ".*?(, FLAG_.*)?, real ([0-9]+) x ([0-9]+).*?, " + "rotation ([0-9]+).*?, layerStack ([0-9]+)", Pattern.MULTILINE); Matcher m = regex.matcher(dumpsysDisplayOutput); diff --git a/server/src/test/java/com/genymobile/scrcpy/CommandParserTest.java b/server/src/test/java/com/genymobile/scrcpy/CommandParserTest.java index e6f57bcb..d74c5d77 100644 --- a/server/src/test/java/com/genymobile/scrcpy/CommandParserTest.java +++ b/server/src/test/java/com/genymobile/scrcpy/CommandParserTest.java @@ -3,6 +3,7 @@ package com.genymobile.scrcpy; import com.genymobile.scrcpy.wrappers.DisplayManager; import android.view.Display; + import org.junit.Assert; import org.junit.Test; @@ -183,4 +184,60 @@ public class CommandParserTest { Assert.assertEquals(1080, displayInfo.getSize().getWidth()); Assert.assertEquals(2280, displayInfo.getSize().getHeight()); } + + @Test + public void testParseDisplayInfoFromDumpsysDisplayAPI29WithNoFlags() { + /* @formatter:off */ + String partialOutput = "Logical Displays: size=2\n" + + " Display 0:\n" + + " mDisplayId=0\n" + + " mLayerStack=0\n" + + " mHasContent=true\n" + + " mAllowedDisplayModes=[1]\n" + + " mRequestedColorMode=0\n" + + " mDisplayOffset=(0, 0)\n" + + " mDisplayScalingDisabled=false\n" + + " mPrimaryDisplayDevice=Built-in Screen\n" + + " mBaseDisplayInfo=DisplayInfo{\"Built-in Screen, displayId 0\", uniqueId \"local:0\", app 3664 x 1920, " + + "real 3664 x 1920, largest app 3664 x 1920, smallest app 3664 x 1920, mode 61, defaultMode 61, modes [" + + "{id=1, width=3664, height=1920, fps=60.000004}, {id=2, width=3664, height=1920, fps=61.000004}, " + + "{id=61, width=3664, height=1920, fps=120.00001}], colorMode 0, supportedColorModes [0], " + + "hdrCapabilities android.view.Display$HdrCapabilities@4a41fe79, rotation 0, density 290 (320.842 x 319.813) dpi, " + + "layerStack 0, appVsyncOff 1000000, presDeadline 8333333, type BUILT_IN, address {port=129, model=0}, " + + "state ON, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, removeMode 0}\n" + + " mOverrideDisplayInfo=DisplayInfo{\"Built-in Screen, displayId 0\", uniqueId \"local:0\", app 3664 x 1920, " + + "real 3664 x 1920, largest app 3664 x 3620, smallest app 1920 x 1876, mode 61, defaultMode 61, modes [" + + "{id=1, width=3664, height=1920, fps=60.000004}, {id=2, width=3664, height=1920, fps=61.000004}, " + + "{id=61, width=3664, height=1920, fps=120.00001}], colorMode 0, supportedColorModes [0], " + + "hdrCapabilities android.view.Display$HdrCapabilities@4a41fe79, rotation 0, density 290 (320.842 x 319.813) dpi, " + + "layerStack 0, appVsyncOff 1000000, presDeadline 8333333, type BUILT_IN, address {port=129, model=0}, " + + "state ON, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, removeMode 0}\n" + + " Display 31:\n" + + " mDisplayId=31\n" + + " mLayerStack=31\n" + + " mHasContent=true\n" + + " mAllowedDisplayModes=[92]\n" + + " mRequestedColorMode=0\n" + + " mDisplayOffset=(0, 0)\n" + + " mDisplayScalingDisabled=false\n" + + " mPrimaryDisplayDevice=PanelLayer-#main\n" + + " mBaseDisplayInfo=DisplayInfo{\"PanelLayer-#main, displayId 31\", uniqueId \"virtual:com.test.system,10040,PanelLayer-#main,0\", " + + "app 800 x 110, real 800 x 110, largest app 800 x 110, smallest app 800 x 110, mode 92, defaultMode 92, modes [" + + "{id=92, width=800, height=110, fps=60.0}], colorMode 0, supportedColorModes [0], " + + "hdrCapabilities null, rotation 0, density 200 (200.0 x 200.0) dpi, layerStack 31, appVsyncOff 0, presDeadline 16666666, " + + "type VIRTUAL, state ON, owner com.test.system (uid 10040), FLAG_PRIVATE, removeMode 1}\n" + + " mOverrideDisplayInfo=DisplayInfo{\"PanelLayer-#main, displayId 31\", uniqueId \"virtual:com.test.system,10040,PanelLayer-#main,0\", " + + "app 800 x 110, real 800 x 110, largest app 800 x 800, smallest app 110 x 110, mode 92, defaultMode 92, modes [" + + "{id=92, width=800, height=110, fps=60.0}], colorMode 0, supportedColorModes [0], " + + "hdrCapabilities null, rotation 0, density 200 (200.0 x 200.0) dpi, layerStack 31, appVsyncOff 0, presDeadline 16666666, " + + "type VIRTUAL, state OFF, owner com.test.system (uid 10040), FLAG_PRIVATE, removeMode 1}\n"; + DisplayInfo displayInfo = DisplayManager.parseDisplayInfo(partialOutput, 31); + Assert.assertNotNull(displayInfo); + Assert.assertEquals(31, displayInfo.getDisplayId()); + Assert.assertEquals(0, displayInfo.getRotation()); + Assert.assertEquals(31, displayInfo.getLayerStack()); + Assert.assertEquals(0, displayInfo.getFlags()); + Assert.assertEquals(800, displayInfo.getSize().getWidth()); + Assert.assertEquals(110, displayInfo.getSize().getHeight()); + } }