aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornihald2000 <54666918+nihald2000@users.noreply.github.com>2024-03-21 22:58:23 +0530
committerGitHub <noreply@github.com>2024-03-21 10:28:23 -0700
commit4c30f2e6d835ac95b47e0fdfdfaffe5e9e63e4f6 (patch)
tree0c89c380eb6a1a7ea427fbe00bcdbb3ded538bca
parentc00e2d62621cf6526c67515b4e50baec79b8339d (diff)
downloadmobly-bundled-snippets-upstream-master.tar.gz
Add `BluetoothHeadsetSnippet` for Bluetooth HFP. (#189)upstream-master
Introduces BluetoothHeadsetClientSnippet for interacting with the Bluetooth Headset Client profile(HFP). The class includes functionality like: * Setting connection policies * Connecting and disconnecting from remote devices * Retrieving connection states * Managing voice recognition
-rw-r--r--src/main/AndroidManifest.xml1
-rw-r--r--src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/profiles/BluetoothHeadsetSnippet.java163
2 files changed, 164 insertions, 0 deletions
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 5d84765..65731eb 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -51,6 +51,7 @@
com.google.android.mobly.snippet.bundled.bluetooth.BluetoothGattServerSnippet,
com.google.android.mobly.snippet.bundled.bluetooth.profiles.BluetoothA2dpSnippet,
com.google.android.mobly.snippet.bundled.bluetooth.profiles.BluetoothHearingAidSnippet,
+ com.google.android.mobly.snippet.bundled.bluetooth.profiles.BluetoothHeadsetSnippet,
com.google.android.mobly.snippet.bundled.BluetoothLeAdvertiserSnippet,
com.google.android.mobly.snippet.bundled.BluetoothLeScannerSnippet,
com.google.android.mobly.snippet.bundled.LogSnippet,
diff --git a/src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/profiles/BluetoothHeadsetSnippet.java b/src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/profiles/BluetoothHeadsetSnippet.java
new file mode 100644
index 0000000..71cb81d
--- /dev/null
+++ b/src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/profiles/BluetoothHeadsetSnippet.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2024 Google Inc.
+ *
+ * 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.google.android.mobly.snippet.bundled.bluetooth.profiles;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.content.IntentFilter;
+import android.os.Bundle;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.google.android.mobly.snippet.Snippet;
+import com.google.android.mobly.snippet.bundled.bluetooth.PairingBroadcastReceiver;
+import com.google.android.mobly.snippet.bundled.utils.JsonSerializer;
+import com.google.android.mobly.snippet.bundled.utils.Utils;
+import com.google.android.mobly.snippet.rpc.Rpc;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+/**
+ * Custom exception class for handling exceptions within the BluetoothHeadsetSnippet.
+ * This exception is meant to encapsulate and convey specific error information related to
+ * BluetoothHeadsetSnippet operations.
+ */
+public class BluetoothHeadsetSnippet implements Snippet {
+
+ private final JsonSerializer mJsonSerializer = new JsonSerializer();
+ private static final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+
+ private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ private static class BluetoothHeadsetSnippetException extends Exception {
+ private static final long serialVersionUID = 1;
+
+ /**
+ * Constructs a BluetoothHeadsetSnippetException with the specified detail message.
+ *
+ * @param msg The detail message providing information about the exception.
+ */
+ BluetoothHeadsetSnippetException(String msg) {
+ super(msg);
+ }
+ }
+
+ private BluetoothHeadset mBluetoothHeadset;
+ private static final int HEADSET = 1;
+
+ private final BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
+ @Override
+ public void onServiceConnected(int var1, BluetoothProfile profile) {
+ if (var1 == HEADSET) {
+ mBluetoothHeadset = (BluetoothHeadset)profile;
+ }
+ }
+ @Override
+ public void onServiceDisconnected(int var1) {
+ if (var1 == HEADSET) {
+ mBluetoothHeadset = null;
+ }
+ }
+ };
+
+ public BluetoothHeadsetSnippet() throws Throwable {
+ IntentFilter filter = new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+ filter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
+ mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET);
+ Utils.waitUntil(() -> mBluetoothHeadset != null, 60);
+ mContext.registerReceiver(new PairingBroadcastReceiver(mContext), filter);
+ }
+
+
+ /**
+ * Returns the connection state for a Bluetooth device with the specified name.
+ *
+ * @param deviceAddress The address of the Bluetooth device.
+ * @return The connection state for the specified device.
+ * @throws BluetoothHeadsetSnippetException If no device with the specified name is connected via HEADSET.
+ */
+ @Rpc(description = "Returns connection state.")
+ public int btHfpGetConnectionState(String deviceAddress) throws BluetoothHeadsetSnippetException {
+ Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
+ for (BluetoothDevice device : pairedDevices) {
+ if (device.getAddress().equalsIgnoreCase(deviceAddress)) {
+ return mBluetoothHeadset.getConnectionState(device);
+ }
+ }
+ throw new BluetoothHeadsetSnippetException("No device with name " + deviceAddress +" is connected via HEADSET.");
+ }
+
+ /**
+ * Starts voice recognition for the Bluetooth device with the specified name.
+ *
+ * @param deviceAddress The address of the Bluetooth device.
+ * @return True if voice recognition is successfully started; false otherwise.
+ * @throws BluetoothHeadsetSnippetException If no device with the specified name is found or if an error
+ * occurs during the startVoiceRecognition operation.
+ */
+ @Rpc(description = "Starts voice recognition.")
+ public boolean btHfpStartVoiceRecognition(String deviceAddress) throws BluetoothHeadsetSnippetException{
+ Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
+ for (BluetoothDevice device : pairedDevices) {
+ if (device.getAddress().equalsIgnoreCase(deviceAddress)) {
+ return mBluetoothHeadset.startVoiceRecognition(device);
+ }
+ }
+ throw new BluetoothHeadsetSnippetException("No device with name " + deviceAddress +" is connected via HEADSET.");
+ }
+
+
+ /**
+ * Stops voice recognition for the Bluetooth device with the specified name.
+ *
+ * @param deviceAddress The address of the Bluetooth device.
+ * @return True if voice recognition is successfully started; false otherwise.
+ * @throws BluetoothHeadsetSnippetException If no device with the specified name is found or if an error
+ * occurs during the startVoiceRecognition operation.
+ */
+ @Rpc(description = "Stops voice recognition.")
+ public boolean btHfpStopVoiceRecognition(String deviceAddress) throws BluetoothHeadsetSnippetException {
+ Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
+ for (BluetoothDevice device : pairedDevices) {
+ if (device.getAddress().equalsIgnoreCase(deviceAddress)) {
+ return mBluetoothHeadset.stopVoiceRecognition(device);
+ }
+ }
+ throw new BluetoothHeadsetSnippetException("No device with name " + deviceAddress +" is connected via HEADSET.");
+ }
+
+ @Rpc(description = "Checks whether the headset supports voice recognition;")
+ public boolean btHfpIsVoiceRecognitionSupported(String deviceAddress) throws BluetoothHeadsetSnippetException {
+ Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
+ for (BluetoothDevice device : pairedDevices) {
+ if (device.getAddress().equalsIgnoreCase(deviceAddress)) {
+ return mBluetoothHeadset.isVoiceRecognitionSupported(device);
+ }
+ }
+ throw new BluetoothHeadsetSnippetException("No device with name " + deviceAddress +" is connected via HEADSET.");
+ }
+ @Rpc(description = "Gets all the devices currently connected via HFP profile.")
+ public ArrayList<Bundle> btHfpGetConnectedDevices() {
+ return mJsonSerializer.serializeBluetoothDeviceList(mBluetoothHeadset.getConnectedDevices());
+ }
+
+ @Override
+ public void shutdown() { }
+}