diff options
| author | William Escande <wescande@google.com> | 2022-12-19 17:54:08 -0800 |
|---|---|---|
| committer | Cherrypicker Worker <android-build-cherrypicker-worker@google.com> | 2022-12-20 21:52:58 +0000 |
| commit | 4ffb8eb23969457b49231a6809e549df7e3333fe (patch) | |
| tree | 8d4489c0b182b3b13a6da94d0b95007799af9ab5 /service/java/com/android/server/bluetooth/BluetoothShellCommand.java | |
| parent | c33fdf19bd24d2b2ffd7b60e120bdf85dd69c8cb (diff) | |
Add wait-for-state command
Disable and enable are async shell command.
This is creating flakyness in test that expect the bluetooth to be
already enabled / disabled.
Test: atest BluetoothInstrumentationTests
Test: atest BluetoothShellCommandTest
Test: atest 'BluetoothTest#AdapterEnableDisable' // net_test_bluetooth
Fix: 261772749
Tag: #refactor
Change-Id: I3ca29dde23a5182ede28eceaf1ac97e4668ab5d5
(cherry picked from commit ca23daa448294ebea1b5cfd421732e85440fe4b9)
Merged-In: I3ca29dde23a5182ede28eceaf1ac97e4668ab5d5
Diffstat (limited to 'service/java/com/android/server/bluetooth/BluetoothShellCommand.java')
| -rw-r--r-- | service/java/com/android/server/bluetooth/BluetoothShellCommand.java | 163 |
1 files changed, 119 insertions, 44 deletions
diff --git a/service/java/com/android/server/bluetooth/BluetoothShellCommand.java b/service/java/com/android/server/bluetooth/BluetoothShellCommand.java index 32b88d209f..8beffa4245 100644 --- a/service/java/com/android/server/bluetooth/BluetoothShellCommand.java +++ b/service/java/com/android/server/bluetooth/BluetoothShellCommand.java @@ -16,6 +16,9 @@ package com.android.server.bluetooth; +import static java.util.Objects.requireNonNull; + +import android.bluetooth.BluetoothAdapter; import android.content.AttributionSource; import android.content.Context; import android.os.Binder; @@ -29,7 +32,7 @@ import com.android.modules.utils.BasicShellCommandHandler; import java.io.PrintWriter; class BluetoothShellCommand extends BasicShellCommandHandler { - private static final String TAG = "BluetoothShellCommand"; + private static final String TAG = BluetoothShellCommand.class.getSimpleName(); private final BluetoothManagerService mManagerService; private final Context mContext; @@ -38,49 +41,111 @@ class BluetoothShellCommand extends BasicShellCommandHandler { final BluetoothCommand[] mBluetoothCommands = { new Enable(), new Disable(), + new WaitForAdapterState(), }; @VisibleForTesting abstract class BluetoothCommand { - abstract String getName(); - // require root permission by default, can be override in command implementation + final boolean mIsPrivileged; + final String mName; + + BluetoothCommand(boolean isPrivileged, String name) { + mIsPrivileged = isPrivileged; + mName = requireNonNull(name, "Command name cannot be null"); + } + + String getName() { + return mName; + } + boolean isMatch(String cmd) { + return mName.equals(cmd); + } boolean isPrivileged() { - return true; + return mIsPrivileged; } - abstract int exec(PrintWriter pw) throws RemoteException; + + abstract int exec(String cmd) throws RemoteException; + abstract void onHelp(PrintWriter pw); } @VisibleForTesting class Enable extends BluetoothCommand { - @Override - String getName() { - return "enable"; + Enable() { + super(false, "enable"); } @Override - boolean isPrivileged() { - return false; + public int exec(String cmd) throws RemoteException { + return mManagerService.enable(AttributionSource.myAttributionSource()) ? 0 : -1; } @Override - public int exec(PrintWriter pw) throws RemoteException { - pw.println("Enabling Bluetooth"); - return mManagerService.enable(AttributionSource.myAttributionSource()) ? 0 : -1; + public void onHelp(PrintWriter pw) { + pw.println(" " + getName()); + pw.println(" Enable Bluetooth on this device."); } } @VisibleForTesting class Disable extends BluetoothCommand { + Disable() { + super(false, "disable"); + } @Override - String getName() { - return "disable"; + public int exec(String cmd) throws RemoteException { + return mManagerService.disable(AttributionSource.myAttributionSource(), true) ? 0 : -1; } @Override - boolean isPrivileged() { - return false; + public void onHelp(PrintWriter pw) { + pw.println(" " + getName()); + pw.println(" Disable Bluetooth on this device."); + } + } + + @VisibleForTesting + class WaitForAdapterState extends BluetoothCommand { + WaitForAdapterState() { + super(false, "wait-for-state"); + } + private int getWaitingState(String in) { + if (!in.startsWith(getName() + ":")) return -1; + String[] split = in.split(":", 2); + if (split.length != 2 || !getName().equals(split[0])) { + String msg = getName() + ": Invalid state format: " + in; + Log.e(TAG, msg); + PrintWriter pw = getErrPrintWriter(); + pw.println(TAG + ": " + msg); + printHelp(pw); + throw new IllegalArgumentException(); + } + switch (split[1]) { + case "STATE_OFF": + return BluetoothAdapter.STATE_OFF; + case "STATE_ON": + return BluetoothAdapter.STATE_ON; + default: + String msg = getName() + ": Invalid state value: " + split[1] + ". From: " + in; + Log.e(TAG, msg); + PrintWriter pw = getErrPrintWriter(); + pw.println(TAG + ": " + msg); + printHelp(pw); + throw new IllegalArgumentException(); + } } @Override - public int exec(PrintWriter pw) throws RemoteException { - pw.println("Disabling Bluetooth"); - return mManagerService.disable(AttributionSource.myAttributionSource(), true) ? 0 : -1; + boolean isMatch(String cmd) { + return getWaitingState(cmd) != -1; + } + @Override + public int exec(String cmd) throws RemoteException { + int ret = mManagerService.waitForManagerState(getWaitingState(cmd)) ? 0 : -1; + Log.d(TAG, cmd + ": Return value is " + ret); // logging as this method can take time + return ret; + } + @Override + public void onHelp(PrintWriter pw) { + pw.println(" " + getName() + ":<STATE>"); + pw.println(" Wait until the adapter state is <STATE>." + + " <STATE> can be one of STATE_OFF | STATE_ON"); + pw.println(" Note: This command can timeout and failed"); } } @@ -91,40 +156,50 @@ class BluetoothShellCommand extends BasicShellCommandHandler { @Override public int onCommand(String cmd) { - if (cmd == null) { - return handleDefaultCommands(null); - } + if (cmd == null) return handleDefaultCommands(null); for (BluetoothCommand bt_cmd : mBluetoothCommands) { - if (cmd.equals(bt_cmd.getName())) { - if (bt_cmd.isPrivileged()) { - final int uid = Binder.getCallingUid(); - if (uid != Process.ROOT_UID) { - throw new SecurityException("Uid " + uid + " does not have access to " - + cmd + " bluetooth command (or such command doesn't exist)"); - } + if (!bt_cmd.isMatch(cmd)) continue; + if (bt_cmd.isPrivileged()) { + final int uid = Binder.getCallingUid(); + if (uid != Process.ROOT_UID) { + throw new SecurityException("Uid " + uid + " does not have access to " + + cmd + " bluetooth command"); } - try { - return bt_cmd.exec(getOutPrintWriter()); - } catch (RemoteException e) { - Log.w(TAG, cmd + ": error\nException: " + e.getMessage()); - getErrPrintWriter().println(cmd + ": error\nException: " + e.getMessage()); - e.rethrowFromSystemServer(); + } + try { + getOutPrintWriter().println(TAG + ": Exec" + cmd); + Log.d(TAG, "Exec " + cmd); + int ret = bt_cmd.exec(cmd); + if (ret == 0) { + String msg = cmd + ": Success"; + Log.d(TAG, msg); + getOutPrintWriter().println(msg); + } else { + String msg = cmd + ": Failed with status=" + ret; + Log.e(TAG, msg); + getErrPrintWriter().println(TAG + ": " + msg); } + return ret; + } catch (RemoteException e) { + Log.w(TAG, cmd + ": error\nException: " + e.getMessage()); + getErrPrintWriter().println(cmd + ": error\nException: " + e.getMessage()); + e.rethrowFromSystemServer(); } } return handleDefaultCommands(cmd); } - @Override - public void onHelp() { - PrintWriter pw = getOutPrintWriter(); - pw.println("Bluetooth Commands:"); + private void printHelp(PrintWriter pw) { + pw.println("Bluetooth Manager Commands:"); pw.println(" help or -h"); pw.println(" Print this help text."); - pw.println(" enable"); - pw.println(" Enable Bluetooth on this device."); - pw.println(" disable"); - pw.println(" Disable Bluetooth on this device."); + for (BluetoothCommand bt_cmd : mBluetoothCommands) { + bt_cmd.onHelp(pw); + } + } + @Override + public void onHelp() { + printHelp(getOutPrintWriter()); } } |
