aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortprotopopov-dev <73544592+tprotopopov-dev@users.noreply.github.com>2020-11-03 18:51:16 -0600
committerGitHub <noreply@github.com>2020-11-04 08:51:16 +0800
commit05ceaf206c46e2360328edd0cc02b30d0b916164 (patch)
tree60192aa62acc065192bf7aa2c50258c9813ed681
parentfaa3ca3d693ea0314e442247be8713f953c582fb (diff)
downloadmobly-bundled-snippets-05ceaf206c46e2360328edd0cc02b30d0b916164.tar.gz
Improve the reliability of bluetooth state change Rpcs. (#134)
-rw-r--r--src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/BluetoothAdapterSnippet.java109
1 files changed, 67 insertions, 42 deletions
diff --git a/src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/BluetoothAdapterSnippet.java b/src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/BluetoothAdapterSnippet.java
index f2ff677..6e66e43 100644
--- a/src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/BluetoothAdapterSnippet.java
+++ b/src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/BluetoothAdapterSnippet.java
@@ -38,7 +38,9 @@ import org.json.JSONException;
/** Snippet class exposing Android APIs in BluetoothAdapter. */
public class BluetoothAdapterSnippet implements Snippet {
+
private static class BluetoothAdapterSnippetException extends Exception {
+
private static final long serialVersionUID = 1;
public BluetoothAdapterSnippetException(String msg) {
@@ -46,8 +48,10 @@ public class BluetoothAdapterSnippet implements Snippet {
}
}
+ // Timeout to measure consistent BT state.
+ private static final int BT_MATCHING_STATE_INTERVAL_SEC = 5;
// Default timeout in seconds.
- private static final int TIMEOUT_TOGGLE_STATE = 30;
+ private static final int TIMEOUT_TOGGLE_STATE_SEC = 30;
private final Context mContext;
private static final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private final JsonSerializer mJsonSerializer = new JsonSerializer();
@@ -94,20 +98,17 @@ public class BluetoothAdapterSnippet implements Snippet {
if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
return;
}
- // If bt is trying to turn off, wait for that to finish before continuing.
- if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_TURNING_OFF) {
- if (!Utils.waitUntil(
- () -> mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF,
- TIMEOUT_TOGGLE_STATE)) {
- Log.e(String.format("BT failed to stabilize after %ss.", TIMEOUT_TOGGLE_STATE));
- }
- }
+ waitForStableBtState();
+
if (!mBluetoothAdapter.enable()) {
- throw new BluetoothAdapterSnippetException("Failed to start enabling bluetooth");
+ throw new BluetoothAdapterSnippetException("Failed to start enabling bluetooth.");
}
- if (!Utils.waitUntil(() -> mBluetoothAdapter.isEnabled(), TIMEOUT_TOGGLE_STATE)) {
+ if (!Utils.waitUntil(
+ () -> mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON,
+ TIMEOUT_TOGGLE_STATE_SEC)) {
throw new BluetoothAdapterSnippetException(
- String.format("Bluetooth did not turn on within %ss.", TIMEOUT_TOGGLE_STATE));
+ String.format(
+ "Bluetooth did not turn on within %ss.", TIMEOUT_TOGGLE_STATE_SEC));
}
}
@@ -116,20 +117,16 @@ public class BluetoothAdapterSnippet implements Snippet {
if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) {
return;
}
- // If bt is trying to turn on, wait for that to finish before continuing.
- if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_TURNING_ON) {
- if (!Utils.waitUntil(
- () -> mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON,
- TIMEOUT_TOGGLE_STATE)) {
- Log.e(String.format("BT failed to stabilize after %ss.", TIMEOUT_TOGGLE_STATE));
- }
- }
+ waitForStableBtState();
if (!mBluetoothAdapter.disable()) {
- throw new BluetoothAdapterSnippetException("Failed to start disabling bluetooth");
+ throw new BluetoothAdapterSnippetException("Failed to start disabling bluetooth.");
}
- if (!Utils.waitUntil(() -> !mBluetoothAdapter.isEnabled(), TIMEOUT_TOGGLE_STATE)) {
+ if (!Utils.waitUntil(
+ () -> mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF,
+ TIMEOUT_TOGGLE_STATE_SEC)) {
throw new BluetoothAdapterSnippetException(
- String.format("Bluetooth did not turn off within %ss.", TIMEOUT_TOGGLE_STATE));
+ String.format(
+ "Bluetooth did not turn off within %ss.", TIMEOUT_TOGGLE_STATE_SEC));
}
}
@@ -203,26 +200,25 @@ public class BluetoothAdapterSnippet implements Snippet {
throw new BluetoothAdapterSnippetException(
"Bluetooth is not enabled, cannot become discoverable.");
}
- // TODO(jwang1013): change it to SDK version for R after R is released.
- if (Build.VERSION.CODENAME.equals("R") || Build.VERSION.SDK_INT > 29) {
- if (!(boolean)
- Utils.invokeByReflection(
- mBluetoothAdapter,
- "setScanMode",
- BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,
- (long) duration * 1000)) {
- throw new BluetoothAdapterSnippetException("Failed to become discoverable.");
- } else {
- if (!(boolean)
- Utils.invokeByReflection(
- mBluetoothAdapter,
- "setScanMode",
- BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,
- duration)) {
- throw new BluetoothAdapterSnippetException("Failed to become discoverable.");
- }
+ if (Build.VERSION.SDK_INT > 29) {
+ if (!(boolean)
+ Utils.invokeByReflection(
+ mBluetoothAdapter,
+ "setScanMode",
+ BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,
+ (long) duration * 1000)) {
+ throw new BluetoothAdapterSnippetException("Failed to become discoverable.");
+ } else {
+ if (!(boolean)
+ Utils.invokeByReflection(
+ mBluetoothAdapter,
+ "setScanMode",
+ BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,
+ duration)) {
+ throw new BluetoothAdapterSnippetException("Failed to become discoverable.");
+ }
+ }
}
- }
}
@Rpc(description = "Cancel ongoing bluetooth discovery.")
@@ -333,4 +329,33 @@ public class BluetoothAdapterSnippet implements Snippet {
}
}
}
+
+ /**
+ * Waits until the bluetooth adapter state has stabilized. We consider BT state stabilized if it
+ * hasn't changed within 5 sec.
+ */
+ private static void waitForStableBtState() throws BluetoothAdapterSnippetException {
+ long timeoutMs = System.currentTimeMillis() + TIMEOUT_TOGGLE_STATE_SEC * 1000;
+ long continuousStateIntervalMs =
+ System.currentTimeMillis() + BT_MATCHING_STATE_INTERVAL_SEC * 1000;
+ int prevState = mBluetoothAdapter.getState();
+ while (System.currentTimeMillis() < timeoutMs) {
+ // Delay.
+ Utils.waitUntil(() -> false, /* timeout= */ 1);
+
+ int currentState = mBluetoothAdapter.getState();
+ if (currentState != prevState) {
+ continuousStateIntervalMs =
+ System.currentTimeMillis() + BT_MATCHING_STATE_INTERVAL_SEC * 1000;
+ }
+ if (continuousStateIntervalMs <= System.currentTimeMillis()) {
+ return;
+ }
+ prevState = currentState;
+ }
+ throw new BluetoothAdapterSnippetException(
+ String.format(
+ "Failed to reach a stable Bluetooth state within %d s",
+ TIMEOUT_TOGGLE_STATE_SEC));
+ }
}