diff options
author | Sergey Prigogin <sprigogin@google.com> | 2024-04-25 17:45:17 -0700 |
---|---|---|
committer | Sergey Prigogin <sprigogin@google.com> | 2024-04-26 16:12:06 +0000 |
commit | e6794b823d8254ac453637696dec609baa39859b (patch) | |
tree | b70f098a29a299eb1f09f5e32ff9e729ce49da1a | |
parent | 777ca5664bd0cfe1f1d92fdf89b20df43f07f15c (diff) | |
download | idea-e6794b823d8254ac453637696dec609baa39859b.tar.gz |
Add dimensions of additional displays to emulator config
...and take them into account when calculating maximum gRPC inbound message size.
Test: EmulatorConfigurationTest
Bug: 335781727
Change-Id: I11363bb12dfd6ca44e5470531c51d46238ac1a69
4 files changed, 87 insertions, 4 deletions
diff --git a/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorConfiguration.kt b/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorConfiguration.kt index cafe085bd1c..8332d1dab6f 100644 --- a/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorConfiguration.kt +++ b/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorConfiguration.kt @@ -23,6 +23,7 @@ import com.android.sdklib.deviceprovisioner.DeviceType import com.android.tools.idea.flags.StudioFlags import com.android.tools.idea.streaming.core.FOLDING_STATE_ICONS import com.google.common.base.Splitter +import com.google.common.collect.ImmutableMap import com.intellij.openapi.diagnostic.thisLogger import com.intellij.openapi.util.text.StringUtil.parseInt import java.awt.Dimension @@ -37,6 +38,7 @@ class EmulatorConfiguration private constructor( val avdFolder: Path, val displaySize: Dimension, val density: Int, + val additionalDisplays: Map<Int, Dimension>, val skinFolder: Path?, val deviceType: DeviceType, val hasOrientationSensors: Boolean, @@ -60,9 +62,7 @@ class EmulatorConfiguration private constructor( */ fun readAvdDefinition(avdId: String, avdFolder: Path): EmulatorConfiguration? { val hardwareIniFile = avdFolder.resolve("hardware-qemu.ini") - val keysToExtract1 = setOf("android.sdk.root", "hw.audioOutput", "hw.lcd.height", "hw.lcd.width", "hw.lcd.density", - "hw.sensor.hinge.resizable.config") - val hardwareIni = readKeyValueFile(hardwareIniFile, keysToExtract1) ?: return null + val hardwareIni = readKeyValueFile(hardwareIniFile) ?: return null val sdkPath = hardwareIni["android.sdk.root"] ?: System.getenv(ANDROID_HOME_ENV) ?: "" val androidSdkRoot = avdFolder.resolve(sdkPath) @@ -72,6 +72,37 @@ class EmulatorConfiguration private constructor( return null } val density = parseInt(hardwareIni["hw.lcd.density"], 0) + + // Extract parameters of secondary displays from lines like "hw.display6.width=400" and "hw.display6.height=600". + val additionalDisplays = mutableMapOf<Int, Dimension>() + for ((key, value) in hardwareIni) { + if (key.startsWith("hw.display")) { + val prefixLength = "hw.display".length + val dotPos = key.indexOf('.', startIndex = prefixLength) + if (dotPos > prefixLength && dotPos < key.length - 1) { + val displayId = parseInt(key.substring(prefixLength, dotPos), 0) + if (displayId > 0) { + val dim = parseInt(value, 0) + if (dim > 0) { + val suffix = key.substring(dotPos + 1) + when (suffix) { + "width" -> additionalDisplays.computeIfAbsent(displayId) { Dimension() }.width = dim + "height" -> additionalDisplays.computeIfAbsent(displayId) { Dimension() }.height = dim + } + } + } + } + } + } + // Remove secondary displays with invalid dimensions. + val iter = additionalDisplays.iterator() + while (iter.hasNext()) { + val size = iter.next().value + if (size.width <= 0 || size.height <= 0) { + iter.remove() + } + } + val hasAudioOutput = hardwareIni["hw.audioOutput"]?.toBoolean() ?: true val configIniFile = avdFolder.resolve("config.ini") @@ -143,6 +174,7 @@ class EmulatorConfiguration private constructor( avdFolder = avdFolder, displaySize = Dimension(displayWidth, displayHeight), density = density, + additionalDisplays = ImmutableMap.copyOf(additionalDisplays), skinFolder = skinPath, deviceType = deviceType, hasOrientationSensors = hasOrientationSensors, diff --git a/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorController.kt b/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorController.kt index 78c33e85811..dbe4a5125e1 100644 --- a/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorController.kt +++ b/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorController.kt @@ -89,6 +89,7 @@ import java.util.Locale import java.util.concurrent.Executor import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicReference +import kotlin.math.max /** * Controls a running Emulator. @@ -217,7 +218,8 @@ class EmulatorController(val emulatorId: EmulatorId, parentDisposable: Disposabl loadSkins(config) val maxPixels = - config.displayModes.maxOfOrNull { it.displaySize.width * it.displaySize.height } ?: (config.displayWidth * config.displayHeight) + config.displayModes.maxOfOrNull { it.displaySize.width * it.displaySize.height } ?: + max(config.displayWidth * config.displayHeight, config.additionalDisplays.values.maxOfOrNull { it.width * it.height } ?: 0) maxInboundMessageSize = maxPixels * 3 + 100 // Three bytes per pixel. connectGrpc(maxInboundMessageSize) diff --git a/streaming/testSrc/com/android/tools/idea/streaming/emulator/EmulatorConfigurationTest.kt b/streaming/testSrc/com/android/tools/idea/streaming/emulator/EmulatorConfigurationTest.kt index 5057e2473f0..9115188a6c4 100644 --- a/streaming/testSrc/com/android/tools/idea/streaming/emulator/EmulatorConfigurationTest.kt +++ b/streaming/testSrc/com/android/tools/idea/streaming/emulator/EmulatorConfigurationTest.kt @@ -25,6 +25,7 @@ import com.google.common.jimfs.Jimfs import com.google.common.truth.Truth.assertThat import com.intellij.openapi.util.SystemInfo import org.junit.Test +import java.awt.Dimension /** * Tests for [EmulatorConfiguration]. @@ -51,6 +52,7 @@ class EmulatorConfigurationTest { assertThat(config?.displayWidth).isEqualTo(1440) assertThat(config?.displayHeight).isEqualTo(2960) assertThat(config?.density).isEqualTo(480) + assertThat(config?.additionalDisplays).isEmpty() assertThat(config?.skinFolder?.toString()?.replace('\\', '/')) .endsWith("tools/adt/idea/artwork/resources/device-art-resources/pixel_3_xl") assertThat(config?.hasAudioOutput).isTrue() @@ -77,6 +79,7 @@ class EmulatorConfigurationTest { assertThat(config?.displayWidth).isEqualTo(1600) assertThat(config?.displayHeight).isEqualTo(2560) assertThat(config?.density).isEqualTo(320) + assertThat(config?.additionalDisplays).isEmpty() assertThat(config?.skinFolder?.toString()?.replace('\\', '/')).isEqualTo("${baseDir}/Android/Sdk/skins/nexus_10") assertThat(config?.hasAudioOutput).isTrue() assertThat(config?.deviceType).isEqualTo(DeviceType.HANDHELD) @@ -88,6 +91,32 @@ class EmulatorConfigurationTest { } @Test + fun testAutomotive() { + // Prepare. + val avdFolder = FakeEmulator.createAutomotiveAvd(avdParentFolder, sdkFolder, api = 32) + + // Act. + val config = EmulatorConfiguration.readAvdDefinition(avdFolder.fileName.toString().substringBeforeLast("."), avdFolder) + + // Assert. + assertThat(config).isNotNull() + assertThat(config?.avdFolder).isEqualTo(avdFolder) + assertThat(config?.avdName).isEqualTo("Automotive 1024p landscape API 32") + assertThat(config?.displayWidth).isEqualTo(1024) + assertThat(config?.displayHeight).isEqualTo(768) + assertThat(config?.density).isEqualTo(160) + assertThat(config?.additionalDisplays).containsExactly(6, Dimension(400, 600), 7, Dimension(3000, 600)) + assertThat(config?.skinFolder).isNull() + assertThat(config?.hasAudioOutput).isTrue() + assertThat(config?.deviceType).isEqualTo(DeviceType.AUTOMOTIVE) + assertThat(config?.hasOrientationSensors).isFalse() + assertThat(config?.initialOrientation).isEqualTo(SkinRotation.LANDSCAPE) + assertThat(config?.displayModes).isEmpty() + assertThat(config?.postures).isEmpty() + assertThat(config?.api).isEqualTo(32) + } + + @Test fun testWatch() { // Prepare. val avdFolder = FakeEmulator.createWatchAvd(avdParentFolder, sdkFolder, api = 30) @@ -102,6 +131,7 @@ class EmulatorConfigurationTest { assertThat(config?.displayWidth).isEqualTo(320) assertThat(config?.displayHeight).isEqualTo(320) assertThat(config?.density).isEqualTo(240) + assertThat(config?.additionalDisplays).isEmpty() assertThat(config?.skinFolder?.toString()).isEqualTo(FakeEmulator.getSkinFolder("wearos_small_round").toString()) assertThat(config?.hasAudioOutput).isTrue() assertThat(config?.deviceType).isEqualTo(DeviceType.WEAR) @@ -127,6 +157,7 @@ class EmulatorConfigurationTest { assertThat(config?.displayWidth).isEqualTo(2208) assertThat(config?.displayHeight).isEqualTo(1840) assertThat(config?.density).isEqualTo(420) + assertThat(config?.additionalDisplays).isEmpty() assertThat(config?.skinFolder?.toString()).isEqualTo(FakeEmulator.getSkinFolder("pixel_fold").toString()) assertThat(config?.hasAudioOutput).isTrue() assertThat(config?.deviceType).isEqualTo(DeviceType.HANDHELD) @@ -155,6 +186,7 @@ class EmulatorConfigurationTest { assertThat(config?.displayWidth).isEqualTo(1600) assertThat(config?.displayHeight).isEqualTo(2428) assertThat(config?.density).isEqualTo(420) + assertThat(config?.additionalDisplays).isEmpty() assertThat(config?.skinFolder).isNull() assertThat(config?.hasAudioOutput).isTrue() assertThat(config?.deviceType).isEqualTo(DeviceType.HANDHELD) @@ -183,6 +215,7 @@ class EmulatorConfigurationTest { assertThat(config?.displayWidth).isEqualTo(1080) assertThat(config?.displayHeight).isEqualTo(2340) assertThat(config?.density).isEqualTo(420) + assertThat(config?.additionalDisplays).isEmpty() assertThat(config?.skinFolder).isNull() assertThat(config?.hasAudioOutput).isTrue() assertThat(config?.deviceType).isEqualTo(DeviceType.HANDHELD) diff --git a/streaming/testUtil/com/android/tools/idea/streaming/emulator/FakeEmulator.kt b/streaming/testUtil/com/android/tools/idea/streaming/emulator/FakeEmulator.kt index 0774ddf682a..365df1ab273 100644 --- a/streaming/testUtil/com/android/tools/idea/streaming/emulator/FakeEmulator.kt +++ b/streaming/testUtil/com/android/tools/idea/streaming/emulator/FakeEmulator.kt @@ -1589,6 +1589,14 @@ class FakeEmulator(val avdFolder: Path, val grpcPort: Int, registrationDirectory hw.sensors.orientation=no hw.sensors.proximity=no hw.trackBall=no + hw.display6.width=400 + hw.display6.height=600 + hw.display6.density=120 + hw.display6.flag=0 + hw.display7.width=3000 + hw.display7.height=600 + hw.display7.density=120 + hw.display7.flag=0 image.sysdir.1=$systemImage runtime.network.latency=none runtime.network.speed=full @@ -1611,6 +1619,14 @@ class FakeEmulator(val avdFolder: Path, val grpcPort: Int, registrationDirectory hw.multi_display_window = false hw.hotplug_multi_display = false hw.screen = multi-touch + hw.display6.width=400 + hw.display6.height=600 + hw.display6.density=120 + hw.display6.flag=0 + hw.display7.width=3000 + hw.display7.height=600 + hw.display7.density=120 + hw.display7.flag=0 hw.dPad = false hw.rotaryInput = false hw.gsmModem = true |