diff options
author | Juan C Nuno <juancnuno@google.com> | 2020-07-10 14:25:36 -0700 |
---|---|---|
committer | Juan C Nuno <juancnuno@google.com> | 2020-07-14 22:10:46 +0000 |
commit | 06d3e77b5758d41bb4dc13a2474a5ade26f4e70f (patch) | |
tree | 748748cb53c3bfc1afe8dfcfc0616834ab238005 | |
parent | 32ccda41be712d4e1614eea4113c293326a11c37 (diff) | |
download | base-mainline-prod.tar.gz |
Set the AVD pathmainline-prod
Bug: 157869510
Test: EmulatorConsoleTest
Change-Id: I0c3fb7b4ecbbd05d4fa996c94fb9fa8fd56fdf56
6 files changed, 113 insertions, 38 deletions
diff --git a/ddmlib/src/main/java/com/android/ddmlib/CommandFailedException.java b/ddmlib/src/main/java/com/android/ddmlib/CommandFailedException.java new file mode 100644 index 0000000000..112e8bc2bb --- /dev/null +++ b/ddmlib/src/main/java/com/android/ddmlib/CommandFailedException.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.ddmlib; + +import com.android.annotations.NonNull; + +public final class CommandFailedException extends RuntimeException { + CommandFailedException() {} + + CommandFailedException(@NonNull String message) { + super(message); + } +} diff --git a/ddmlib/src/main/java/com/android/ddmlib/EmulatorConsole.java b/ddmlib/src/main/java/com/android/ddmlib/EmulatorConsole.java index 5b671ecccc..8831362908 100644 --- a/ddmlib/src/main/java/com/android/ddmlib/EmulatorConsole.java +++ b/ddmlib/src/main/java/com/android/ddmlib/EmulatorConsole.java @@ -31,10 +31,10 @@ import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.security.InvalidParameterException; -import java.util.Arrays; import java.util.Formatter; import java.util.HashMap; import java.util.Locale; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -375,58 +375,59 @@ public final class EmulatorConsole { */ @Nullable public synchronized String getAvdName() { - return getOutput(COMMAND_AVD_NAME); + try { + return getOutput(COMMAND_AVD_NAME); + } catch (CommandFailedException exception) { + return exception.getMessage(); + } catch (Exception exception) { + // noinspection ConstantConditions + if (exception instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + + return null; + } } /** * Returns the absolute path to the virtual device in the file system. The path is operating - * system dependent; it will have / name separators on Linux and \ separators on Windows. The - * subcommand was added to the emulator in Version 30.0.18. + * system dependent; it will have / name separators on Linux and \ separators on Windows. * - * @return the AVD path. If the command failed returns the error message after "KO: " or null. - * Returns the error message "bad sub-command" in versions prior to 30.0.18. + * @throws CommandFailedException If the subcommand failed or if the emulator's version is older + * than 30.0.18 */ - @Nullable + @NonNull public synchronized String getAvdPath() { return getOutput(COMMAND_AVD_PATH); } - @Nullable + @NonNull private String getOutput(@NonNull String command) { if (!sendCommand(command)) { - return null; + throw new CommandFailedException(); } - String[] lines = readLines(); - - if (lines == null) { - return null; - } - - return processOutput(lines); + return processOutput(Objects.requireNonNull(readLines())); } - @Nullable + @NonNull @VisibleForTesting static String processOutput(@NonNull String[] lines) { if (lines.length == 0) { - return null; + throw new IllegalArgumentException(); } Matcher matcher = RE_KO.matcher(lines[lines.length - 1]); if (matcher.matches()) { - return matcher.group(1); + throw new CommandFailedException(matcher.group(1)); } if (lines.length >= 2 && lines[lines.length - 1].equals("OK")) { return lines[lines.length - 2]; } - Log.w(LOG_TAG, "Unexpected output"); - Arrays.asList(lines).forEach(line -> Log.d(LOG_TAG, line)); - - return null; + throw new IllegalArgumentException(String.join(System.lineSeparator(), lines)); } /** diff --git a/ddmlib/src/main/java/com/android/ddmlib/IDevice.java b/ddmlib/src/main/java/com/android/ddmlib/IDevice.java index 7142a21307..5d307bb657 100644 --- a/ddmlib/src/main/java/com/android/ddmlib/IDevice.java +++ b/ddmlib/src/main/java/com/android/ddmlib/IDevice.java @@ -171,6 +171,16 @@ public interface IDevice extends IShellEnabledDevice { @Nullable String getAvdName(); + /** + * Returns the absolute path to the virtual device in the file system. The path is operating + * system dependent; it will have / name separators on Linux and \ separators on Windows. + * + * @return the AVD path or null if this is a physical device, the emulator console subcommand + * failed, or the emulator's version is older than 30.0.18 + */ + @Nullable + String getAvdPath(); + /** Returns the state of the device. */ DeviceState getState(); diff --git a/ddmlib/src/main/java/com/android/ddmlib/internal/DeviceImpl.java b/ddmlib/src/main/java/com/android/ddmlib/internal/DeviceImpl.java index 804f357d13..852fbe0de8 100644 --- a/ddmlib/src/main/java/com/android/ddmlib/internal/DeviceImpl.java +++ b/ddmlib/src/main/java/com/android/ddmlib/internal/DeviceImpl.java @@ -80,6 +80,8 @@ public final class DeviceImpl implements IDevice { /** Name of the AVD */ private String mAvdName = null; + @Nullable private String mAvdPath; + /** State of the device. */ private DeviceState mState; @@ -172,6 +174,20 @@ public final class DeviceImpl implements IDevice { mAvdName = avdName; } + @Nullable + @Override + public String getAvdPath() { + return mAvdPath; + } + + void setAvdPath(@NonNull String avdPath) { + if (!isEmulator()) { + throw new IllegalStateException(); + } + + mAvdPath = avdPath; + } + @Override public String getName() { if (mName != null) { @@ -772,7 +788,7 @@ public final class DeviceImpl implements IDevice { String.format("%s:%s", namespace.getType(), remoteSocketName)); //$NON-NLS-1$ } - @VisibleForTesting + // @VisibleForTesting public DeviceImpl(ClientTracker clientTracer, String serialNumber, DeviceState deviceState) { mClientTracer = clientTracer; mSerialNumber = serialNumber; diff --git a/ddmlib/src/main/java/com/android/ddmlib/internal/DeviceMonitor.java b/ddmlib/src/main/java/com/android/ddmlib/internal/DeviceMonitor.java index 168d58ecca..a7505f7917 100644 --- a/ddmlib/src/main/java/com/android/ddmlib/internal/DeviceMonitor.java +++ b/ddmlib/src/main/java/com/android/ddmlib/internal/DeviceMonitor.java @@ -21,6 +21,7 @@ import com.android.annotations.Nullable; import com.android.annotations.concurrency.GuardedBy; import com.android.ddmlib.AndroidDebugBridge; import com.android.ddmlib.ClientTracker; +import com.android.ddmlib.CommandFailedException; import com.android.ddmlib.DdmPreferences; import com.android.ddmlib.EmulatorConsole; import com.android.ddmlib.IDevice; @@ -252,7 +253,7 @@ public final class DeviceMonitor implements ClientTracker { } for (DeviceImpl device : newlyOnline) { - queryAvdName(device); + setProperties(device); // Initiate a property fetch so that future requests can be served out of this cache. // This is necessary for backwards compatibility @@ -274,16 +275,26 @@ public final class DeviceMonitor implements ClientTracker { } } - private static void queryAvdName(@NonNull DeviceImpl device) { + private static void setProperties(@NonNull DeviceImpl device) { if (!device.isEmulator()) { return; } EmulatorConsole console = EmulatorConsole.getConsole(device); - if (console != null) { - device.setAvdName(console.getAvdName()); - console.close(); + + if (console == null) { + return; } + + device.setAvdName(console.getAvdName()); + + try { + device.setAvdPath(console.getAvdPath()); + } catch (CommandFailedException exception) { + Log.e("DeviceMonitor", exception); + } + + console.close(); } private class DeviceListUpdateListener implements DeviceListMonitorTask.UpdateListener { diff --git a/ddmlib/src/test/java/com/android/ddmlib/EmulatorConsoleTest.java b/ddmlib/src/test/java/com/android/ddmlib/EmulatorConsoleTest.java index 0c9303a7c7..5a44045a58 100644 --- a/ddmlib/src/test/java/com/android/ddmlib/EmulatorConsoleTest.java +++ b/ddmlib/src/test/java/com/android/ddmlib/EmulatorConsoleTest.java @@ -17,6 +17,7 @@ package com.android.ddmlib; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,10 +51,13 @@ public final class EmulatorConsoleTest { String[] lines = {}; // Act - Object output = EmulatorConsole.processOutput(lines); - + try { + EmulatorConsole.processOutput(lines); + fail(); + } // Assert - assertNull(output); + catch (IllegalArgumentException ignored) { + } } @Test @@ -86,10 +90,14 @@ public final class EmulatorConsoleTest { }; // Act - Object output = EmulatorConsole.processOutput(lines); - + try { + EmulatorConsole.processOutput(lines); + fail(); + } // Assert - assertEquals("bad sub-command", output); + catch (CommandFailedException exception) { + assertEquals("bad sub-command", exception.getMessage()); + } } @Test @@ -145,9 +153,12 @@ public final class EmulatorConsoleTest { }; // Act - Object output = EmulatorConsole.processOutput(lines); - + try { + EmulatorConsole.processOutput(lines); + fail(); + } // Assert - assertNull(output); + catch (IllegalArgumentException ignored) { + } } } |