diff options
author | nihald2000 <54666918+nihald2000@users.noreply.github.com> | 2024-03-21 22:58:23 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-21 10:28:23 -0700 |
commit | 4c30f2e6d835ac95b47e0fdfdfaffe5e9e63e4f6 (patch) | |
tree | 0c89c380eb6a1a7ea427fbe00bcdbb3ded538bca | |
parent | c00e2d62621cf6526c67515b4e50baec79b8339d (diff) | |
download | mobly-bundled-snippets-4c30f2e6d835ac95b47e0fdfdfaffe5e9e63e4f6.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.xml | 1 | ||||
-rw-r--r-- | src/main/java/com/google/android/mobly/snippet/bundled/bluetooth/profiles/BluetoothHeadsetSnippet.java | 163 |
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() { } +} |