summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml9
-rw-r--r--jni/Android.bp1
-rw-r--r--jni/com_android_bluetooth.h2
-rw-r--r--jni/com_android_bluetooth_btservice_AdapterService.cpp7
-rw-r--r--jni/com_android_bluetooth_hap_client.cpp645
-rw-r--r--res/drawable/ic_bluetooth_share_icon.xml28
-rw-r--r--res/mipmap-anydpi/bt_share.xml2
-rw-r--r--res/values/config.xml1
-rw-r--r--src/com/android/bluetooth/a2dp/A2dpService.java212
-rw-r--r--src/com/android/bluetooth/a2dp/A2dpStateMachine.java40
-rw-r--r--src/com/android/bluetooth/acm/AcmServIntf.java21
-rw-r--r--src/com/android/bluetooth/apm/CallAudioIntf.java23
-rw-r--r--src/com/android/bluetooth/apm/MediaAudioIntf.java40
-rw-r--r--src/com/android/bluetooth/btservice/ActiveDeviceManager.java87
-rw-r--r--src/com/android/bluetooth/btservice/AdapterService.java102
-rw-r--r--src/com/android/bluetooth/btservice/Config.java20
-rw-r--r--src/com/android/bluetooth/btservice/PhonePolicy.java22
-rw-r--r--src/com/android/bluetooth/btservice/ServiceFactory.java5
-rw-r--r--src/com/android/bluetooth/btservice/storage/Metadata.java5
-rw-r--r--src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java3
-rw-r--r--src/com/android/bluetooth/hap/HapClientNativeInterface.java425
-rw-r--r--src/com/android/bluetooth/hap/HapClientService.java1674
-rw-r--r--src/com/android/bluetooth/hap/HapClientStackEvent.java272
-rw-r--r--src/com/android/bluetooth/hap/HapClientStateMachine.java589
-rw-r--r--src/com/android/bluetooth/hfp/HeadsetA2dpSync.java39
-rw-r--r--src/com/android/bluetooth/hfp/HeadsetService.java140
-rw-r--r--src/com/android/bluetooth/hfp/HeadsetStateMachine.java8
-rw-r--r--src/com/android/bluetooth/le_audio/LeAudioService.java228
-rw-r--r--tests/unit/src/com/android/bluetooth/btservice/storage/schemas/com.android.bluetooth.btservice.storage.MetadataDatabase/114.json (renamed from 114.json)0
29 files changed, 80 insertions, 4570 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3f5293e7f..cd409d32c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -456,15 +456,6 @@
<action android:name="android.bluetooth.IBluetoothLeAudio" />
</intent-filter>
</service>
- <!-- Hearing Aid Profile (HAP) client Profile Service -->
- <service android:process="@string/process"
- android:name="com.android.bluetooth.hap.HapClientService"
- android:enabled="@bool/profile_supported_hap_client"
- android:exported="true">
- <intent-filter>
- <action android:name="android.bluetooth.IBluetoothHapClient"/>
- </intent-filter>
- </service>
<service
android:process="@string/process"
android:name = "com.android.bluetooth.lebroadcast.BassClientService"
diff --git a/jni/Android.bp b/jni/Android.bp
index b598ec660..7414868e0 100644
--- a/jni/Android.bp
+++ b/jni/Android.bp
@@ -42,7 +42,6 @@ cc_library_shared {
"com_android_bluetooth_hid_host.cpp",
"com_android_bluetooth_hid_device.cpp",
"com_android_bluetooth_hearing_aid.cpp",
- "com_android_bluetooth_hap_client.cpp",
"com_android_bluetooth_pan.cpp",
"com_android_bluetooth_gatt.cpp",
"com_android_bluetooth_sdp.cpp",
diff --git a/jni/com_android_bluetooth.h b/jni/com_android_bluetooth.h
index 572c3e6bd..40e0af4cc 100644
--- a/jni/com_android_bluetooth.h
+++ b/jni/com_android_bluetooth.h
@@ -169,8 +169,6 @@ int register_com_android_bluetooth_btservice_vendor_socket(JNIEnv* env);
int register_com_android_bluetooth_hearing_aid(JNIEnv* env);
-int register_com_android_bluetooth_hap_client(JNIEnv* env);
-
int register_com_android_bluetooth_avrcp_ext(JNIEnv* env);
int register_com_android_bluetooth_ba(JNIEnv* env);
diff --git a/jni/com_android_bluetooth_btservice_AdapterService.cpp b/jni/com_android_bluetooth_btservice_AdapterService.cpp
index 2780a8bbc..bc9421025 100644
--- a/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -1903,13 +1903,6 @@ jint JNI_OnLoad(JavaVM *jvm, void *reserved) {
return JNI_ERR;
}
- status = android::register_com_android_bluetooth_hap_client(e);
- if (status < 0) {
- ALOGE("jni le audio hearing access client registration failure: %d",
- status);
- return JNI_ERR;
- }
-
status = android::register_com_android_bluetooth_avrcp_ext(e);
if (status < 0) {
ALOGE("jni avrcp_ext registration failure: %d", status);
diff --git a/jni/com_android_bluetooth_hap_client.cpp b/jni/com_android_bluetooth_hap_client.cpp
deleted file mode 100644
index 1d77a27eb..000000000
--- a/jni/com_android_bluetooth_hap_client.cpp
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.
- */
-
-#define LOG_TAG "BluetoothHapClientJni"
-
-#include <string.h>
-
-#include <shared_mutex>
-
-#include "base/logging.h"
-#include "com_android_bluetooth.h"
-#include "hardware/bt_has.h"
-
-using bluetooth::has::ConnectionState;
-using bluetooth::has::ErrorCode;
-using bluetooth::has::HasClientCallbacks;
-using bluetooth::has::HasClientInterface;
-using bluetooth::has::PresetInfo;
-using bluetooth::has::PresetInfoReason;
-
-namespace android {
-static jmethodID method_onConnectionStateChanged;
-static jmethodID method_onDeviceAvailable;
-static jmethodID method_onFeaturesUpdate;
-static jmethodID method_onActivePresetSelected;
-static jmethodID method_onGroupActivePresetSelected;
-static jmethodID method_onActivePresetSelectError;
-static jmethodID method_onGroupActivePresetSelectError;
-static jmethodID method_onPresetInfo;
-static jmethodID method_onGroupPresetInfo;
-static jmethodID method_onPresetInfoError;
-static jmethodID method_onGroupPresetInfoError;
-static jmethodID method_onPresetNameSetError;
-static jmethodID method_onGroupPresetNameSetError;
-
-static HasClientInterface* sHasClientInterface = nullptr;
-static std::shared_timed_mutex interface_mutex;
-
-static jobject mCallbacksObj = nullptr;
-static std::shared_timed_mutex callbacks_mutex;
-
-static struct {
- jclass clazz;
- jmethodID constructor;
- jmethodID getCodecType;
- jmethodID getCodecPriority;
- jmethodID getSampleRate;
- jmethodID getBitsPerSample;
- jmethodID getChannelMode;
- jmethodID getCodecSpecific1;
- jmethodID getCodecSpecific2;
- jmethodID getCodecSpecific3;
- jmethodID getCodecSpecific4;
-} android_bluetooth_BluetoothHapPresetInfo;
-
-class HasClientCallbacksImpl : public HasClientCallbacks {
- public:
- ~HasClientCallbacksImpl() = default;
-
- void OnConnectionState(ConnectionState state,
- const RawAddress& bd_addr) override {
- LOG(INFO) << __func__;
-
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- LOG(ERROR) << "Failed to new bd addr jbyteArray for connection state";
- return;
- }
-
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
- (jbyte*)&bd_addr);
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged,
- (jint)state, addr.get());
- }
-
- void OnDeviceAvailable(const RawAddress& bd_addr, uint8_t features) override {
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- LOG(ERROR) << "Failed to new bd addr jbyteArray for device available";
- return;
- }
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
- (jbyte*)&bd_addr);
-
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDeviceAvailable,
- addr.get(), (jint)features);
- }
-
- void OnFeaturesUpdate(const RawAddress& bd_addr, uint8_t features) override {
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- LOG(ERROR) << "Failed to new bd addr jbyteArray for device available";
- return;
- }
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
- (jbyte*)&bd_addr);
-
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onFeaturesUpdate,
- addr.get(), (jint)features);
- }
-
- void OnActivePresetSelected(std::variant<RawAddress, int> addr_or_group_id,
- uint8_t preset_index) override {
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- if (std::holds_alternative<RawAddress>(addr_or_group_id)) {
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- LOG(ERROR) << "Failed to new bd addr jbyteArray for preset selected";
- return;
- }
- sCallbackEnv->SetByteArrayRegion(
- addr.get(), 0, sizeof(RawAddress),
- (jbyte*)&std::get<RawAddress>(addr_or_group_id));
-
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onActivePresetSelected,
- addr.get(), (jint)preset_index);
- } else {
- sCallbackEnv->CallVoidMethod(
- mCallbacksObj, method_onGroupActivePresetSelected,
- std::get<int>(addr_or_group_id), (jint)preset_index);
- }
- }
-
- void OnActivePresetSelectError(std::variant<RawAddress, int> addr_or_group_id,
- ErrorCode error_code) override {
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- if (std::holds_alternative<RawAddress>(addr_or_group_id)) {
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- LOG(ERROR)
- << "Failed to new bd addr jbyteArray for preset select error";
- return;
- }
- sCallbackEnv->SetByteArrayRegion(
- addr.get(), 0, sizeof(RawAddress),
- (jbyte*)&std::get<RawAddress>(addr_or_group_id));
-
- sCallbackEnv->CallVoidMethod(mCallbacksObj,
- method_onActivePresetSelectError, addr.get(),
- (jint)error_code);
- } else {
- sCallbackEnv->CallVoidMethod(
- mCallbacksObj, method_onGroupActivePresetSelectError,
- std::get<int>(addr_or_group_id), (jint)error_code);
- }
- }
-
- void OnPresetInfo(std::variant<RawAddress, int> addr_or_group_id,
- PresetInfoReason info_reason,
- std::vector<PresetInfo> detail_records) override {
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- jsize i = 0;
- jobjectArray presets_array = sCallbackEnv->NewObjectArray(
- (jsize)detail_records.size(),
- android_bluetooth_BluetoothHapPresetInfo.clazz, nullptr);
-
- const char null_str[] = "";
- for (auto const& info : detail_records) {
- const char* name = info.preset_name.c_str();
- if (!sCallbackEnv.isValidUtf(name)) {
- ALOGE("%s: name is not a valid UTF string.", __func__);
- name = null_str;
- }
-
- ScopedLocalRef<jstring> name_str(sCallbackEnv.get(),
- sCallbackEnv->NewStringUTF(name));
- if (!name_str.get()) {
- LOG(ERROR) << "Failed to new preset name String for preset name";
- return;
- }
-
- jobject infoObj = sCallbackEnv->NewObject(
- android_bluetooth_BluetoothHapPresetInfo.clazz,
- android_bluetooth_BluetoothHapPresetInfo.constructor,
- (jint)info.preset_index, name_str.get(), (jboolean)info.writable,
- (jboolean)info.available);
- sCallbackEnv->SetObjectArrayElement(presets_array, i++, infoObj);
- sCallbackEnv->DeleteLocalRef(infoObj);
- }
-
- if (std::holds_alternative<RawAddress>(addr_or_group_id)) {
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- LOG(ERROR) << "Failed to new bd addr jbyteArray for preset name";
- return;
- }
- sCallbackEnv->SetByteArrayRegion(
- addr.get(), 0, sizeof(RawAddress),
- (jbyte*)&std::get<RawAddress>(addr_or_group_id));
-
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onPresetInfo,
- addr.get(), (jint)info_reason,
- presets_array);
- } else {
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGroupPresetInfo,
- std::get<int>(addr_or_group_id),
- (jint)info_reason, presets_array);
- }
- }
-
- virtual void OnPresetInfoError(std::variant<RawAddress, int> addr_or_group_id,
- uint8_t preset_index,
- ErrorCode error_code) override {
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- if (std::holds_alternative<RawAddress>(addr_or_group_id)) {
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- LOG(ERROR)
- << "Failed to new bd addr jbyteArray for preset name get error";
- return;
- }
- sCallbackEnv->SetByteArrayRegion(
- addr.get(), 0, sizeof(RawAddress),
- (jbyte*)&std::get<RawAddress>(addr_or_group_id));
-
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onPresetInfoError,
- addr.get(), (jint)preset_index,
- (jint)error_code);
- } else {
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGroupPresetInfoError,
- std::get<int>(addr_or_group_id),
- (jint)preset_index, (jint)error_code);
- }
- }
-
- void OnSetPresetNameError(std::variant<RawAddress, int> addr_or_group_id,
- uint8_t preset_index,
- ErrorCode error_code) override {
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- if (std::holds_alternative<RawAddress>(addr_or_group_id)) {
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- LOG(ERROR)
- << "Failed to new bd addr jbyteArray for preset name set error";
- return;
- }
- sCallbackEnv->SetByteArrayRegion(
- addr.get(), 0, sizeof(RawAddress),
- (jbyte*)&std::get<RawAddress>(addr_or_group_id));
-
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onPresetNameSetError,
- addr.get(), (jint)preset_index,
- (jint)error_code);
- } else {
- sCallbackEnv->CallVoidMethod(mCallbacksObj,
- method_onGroupPresetNameSetError,
- std::get<int>(addr_or_group_id),
- (jint)preset_index, (jint)error_code);
- }
- }
-};
-
-static HasClientCallbacksImpl sHasClientCallbacks;
-
-static void classInitNative(JNIEnv* env, jclass clazz) {
- jclass jniBluetoothBluetoothHapPresetInfoClass =
- env->FindClass("android/bluetooth/BluetoothHapPresetInfo");
- CHECK(jniBluetoothBluetoothHapPresetInfoClass != NULL);
-
- android_bluetooth_BluetoothHapPresetInfo.constructor =
- env->GetMethodID(jniBluetoothBluetoothHapPresetInfoClass, "<init>",
- "(ILjava/lang/String;ZZ)V");
-
- method_onConnectionStateChanged =
- env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
-
- method_onDeviceAvailable =
- env->GetMethodID(clazz, "onDeviceAvailable", "([BI)V");
-
- method_onFeaturesUpdate =
- env->GetMethodID(clazz, "onFeaturesUpdate", "([BI)V");
-
- method_onActivePresetSelected =
- env->GetMethodID(clazz, "onActivePresetSelected", "([BI)V");
-
- method_onGroupActivePresetSelected =
- env->GetMethodID(clazz, "onActivePresetGroupSelected", "(II)V");
-
- method_onActivePresetSelectError =
- env->GetMethodID(clazz, "onActivePresetSelectError", "([BI)V");
-
- method_onGroupActivePresetSelectError =
- env->GetMethodID(clazz, "onActivePresetGroupSelectError", "(II)V");
-
- method_onPresetInfo =
- env->GetMethodID(clazz, "onPresetInfo",
- "([BI[Landroid/bluetooth/BluetoothHapPresetInfo;)V");
-
- method_onGroupPresetInfo =
- env->GetMethodID(clazz, "onGroupPresetInfo",
- "(II[Landroid/bluetooth/BluetoothHapPresetInfo;)V");
-
- method_onPresetNameSetError =
- env->GetMethodID(clazz, "onPresetNameSetError", "([BII)V");
-
- method_onGroupPresetNameSetError =
- env->GetMethodID(clazz, "onGroupPresetNameSetError", "(III)V");
-
- method_onPresetInfoError =
- env->GetMethodID(clazz, "onPresetInfoError", "([BII)V");
-
- method_onGroupPresetInfoError =
- env->GetMethodID(clazz, "onGroupPresetInfoError", "(III)V");
-
- LOG(INFO) << __func__ << ": succeeds";
-}
-
-static void initNative(JNIEnv* env, jobject object) {
- std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
- std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);
-
- const bt_interface_t* btInf = getBluetoothInterface();
- if (btInf == nullptr) {
- LOG(ERROR) << "Bluetooth module is not loaded";
- return;
- }
-
- if (sHasClientInterface != nullptr) {
- LOG(INFO) << "Cleaning up HearingAid Interface before initializing...";
- sHasClientInterface->Cleanup();
- sHasClientInterface = nullptr;
- }
-
- if (mCallbacksObj != nullptr) {
- LOG(INFO) << "Cleaning up HearingAid callback object";
- env->DeleteGlobalRef(mCallbacksObj);
- mCallbacksObj = nullptr;
- }
-
- if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) {
- LOG(ERROR) << "Failed to allocate Global Ref for Hearing Access Callbacks";
- return;
- }
-
- android_bluetooth_BluetoothHapPresetInfo.clazz = (jclass)env->NewGlobalRef(
- env->FindClass("android/bluetooth/BluetoothHapPresetInfo"));
- if (android_bluetooth_BluetoothHapPresetInfo.clazz == nullptr) {
- ALOGE("%s: Failed to allocate Global Ref for BluetoothHapPresetInfo class",
- __func__);
- return;
- }
-
- sHasClientInterface = (HasClientInterface*)btInf->get_profile_interface(
- BT_PROFILE_HAP_CLIENT_ID);
- if (sHasClientInterface == nullptr) {
- LOG(ERROR)
- << "Failed to get Bluetooth Hearing Access Service Client Interface";
- return;
- }
-
- sHasClientInterface->Init(&sHasClientCallbacks);
-}
-
-static void cleanupNative(JNIEnv* env, jobject object) {
- std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
- std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);
-
- const bt_interface_t* btInf = getBluetoothInterface();
- if (btInf == nullptr) {
- LOG(ERROR) << "Bluetooth module is not loaded";
- return;
- }
-
- if (sHasClientInterface != nullptr) {
- sHasClientInterface->Cleanup();
- sHasClientInterface = nullptr;
- }
-
- if (mCallbacksObj != nullptr) {
- env->DeleteGlobalRef(mCallbacksObj);
- mCallbacksObj = nullptr;
- }
-}
-
-static jboolean connectHapClientNative(JNIEnv* env, jobject object,
- jbyteArray address) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return JNI_FALSE;
- }
-
- jbyte* addr = env->GetByteArrayElements(address, nullptr);
- if (!addr) {
- jniThrowIOException(env, EINVAL);
- return JNI_FALSE;
- }
-
- RawAddress* tmpraw = (RawAddress*)addr;
- sHasClientInterface->Connect(*tmpraw);
- env->ReleaseByteArrayElements(address, addr, 0);
- return JNI_TRUE;
-}
-
-static jboolean disconnectHapClientNative(JNIEnv* env, jobject object,
- jbyteArray address) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return JNI_FALSE;
- }
-
- jbyte* addr = env->GetByteArrayElements(address, nullptr);
- if (!addr) {
- jniThrowIOException(env, EINVAL);
- return JNI_FALSE;
- }
-
- RawAddress* tmpraw = (RawAddress*)addr;
- sHasClientInterface->Disconnect(*tmpraw);
- env->ReleaseByteArrayElements(address, addr, 0);
- return JNI_TRUE;
-}
-
-static void selectActivePresetNative(JNIEnv* env, jobject object,
- jbyteArray address, jint preset_index) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return;
- }
-
- jbyte* addr = env->GetByteArrayElements(address, nullptr);
- if (!addr) {
- jniThrowIOException(env, EINVAL);
- return;
- }
-
- RawAddress* tmpraw = (RawAddress*)addr;
- sHasClientInterface->SelectActivePreset(*tmpraw, preset_index);
- env->ReleaseByteArrayElements(address, addr, 0);
-}
-
-static void groupSelectActivePresetNative(JNIEnv* env, jobject object,
- jint group_id, jint preset_index) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return;
- }
-
- sHasClientInterface->SelectActivePreset(group_id, preset_index);
-}
-
-static void nextActivePresetNative(JNIEnv* env, jobject object,
- jbyteArray address) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return;
- }
-
- jbyte* addr = env->GetByteArrayElements(address, nullptr);
- if (!addr) {
- jniThrowIOException(env, EINVAL);
- return;
- }
-
- RawAddress* tmpraw = (RawAddress*)addr;
- sHasClientInterface->NextActivePreset(*tmpraw);
- env->ReleaseByteArrayElements(address, addr, 0);
-}
-
-static void groupNextActivePresetNative(JNIEnv* env, jobject object,
- jint group_id) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return;
- }
-
- sHasClientInterface->NextActivePreset(group_id);
-}
-
-static void previousActivePresetNative(JNIEnv* env, jobject object,
- jbyteArray address) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return;
- }
-
- jbyte* addr = env->GetByteArrayElements(address, nullptr);
- if (!addr) {
- jniThrowIOException(env, EINVAL);
- return;
- }
-
- RawAddress* tmpraw = (RawAddress*)addr;
- sHasClientInterface->PreviousActivePreset(*tmpraw);
- env->ReleaseByteArrayElements(address, addr, 0);
-}
-
-static void groupPreviousActivePresetNative(JNIEnv* env, jobject object,
- jint group_id) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return;
- }
-
- sHasClientInterface->PreviousActivePreset(group_id);
-}
-
-static void getPresetInfoNative(JNIEnv* env, jobject object, jbyteArray address,
- jint preset_index) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return;
- }
-
- jbyte* addr = env->GetByteArrayElements(address, nullptr);
- if (!addr) {
- jniThrowIOException(env, EINVAL);
- return;
- }
-
- RawAddress* tmpraw = (RawAddress*)addr;
- sHasClientInterface->GetPresetInfo(*tmpraw, preset_index);
- env->ReleaseByteArrayElements(address, addr, 0);
-}
-
-static void setPresetNameNative(JNIEnv* env, jobject object, jbyteArray address,
- jint preset_index, jstring name) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return;
- }
-
- jbyte* addr = env->GetByteArrayElements(address, nullptr);
- if (!addr) {
- jniThrowIOException(env, EINVAL);
- return;
- }
-
- std::string name_str;
- if (name != nullptr) {
- const char* value = env->GetStringUTFChars(name, nullptr);
- name_str = std::string(value);
- env->ReleaseStringUTFChars(name, value);
- }
-
- RawAddress* tmpraw = (RawAddress*)addr;
- sHasClientInterface->SetPresetName(*tmpraw, preset_index,
- std::move(name_str));
- env->ReleaseByteArrayElements(address, addr, 0);
-}
-
-static void groupSetPresetNameNative(JNIEnv* env, jobject object, jint group_id,
- jint preset_index, jstring name) {
- std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
- if (!sHasClientInterface) {
- LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface";
- return;
- }
-
- std::string name_str;
- if (name != nullptr) {
- const char* value = env->GetStringUTFChars(name, nullptr);
- name_str = std::string(value);
- env->ReleaseStringUTFChars(name, value);
- }
-
- sHasClientInterface->SetPresetName(group_id, preset_index,
- std::move(name_str));
-}
-
-static JNINativeMethod sMethods[] = {
- {"classInitNative", "()V", (void*)classInitNative},
- {"initNative", "()V", (void*)initNative},
- {"cleanupNative", "()V", (void*)cleanupNative},
- {"connectHapClientNative", "([B)Z", (void*)connectHapClientNative},
- {"disconnectHapClientNative", "([B)Z", (void*)disconnectHapClientNative},
- {"selectActivePresetNative", "([BI)V", (void*)selectActivePresetNative},
- {"groupSelectActivePresetNative", "(II)V",
- (void*)groupSelectActivePresetNative},
- {"nextActivePresetNative", "([B)V", (void*)nextActivePresetNative},
- {"groupNextActivePresetNative", "(I)V", (void*)groupNextActivePresetNative},
- {"previousActivePresetNative", "([B)V", (void*)previousActivePresetNative},
- {"groupPreviousActivePresetNative", "(I)V",
- (void*)groupPreviousActivePresetNative},
- {"getPresetInfoNative", "([BI)V", (void*)getPresetInfoNative},
- {"setPresetNameNative", "([BILjava/lang/String;)V",
- (void*)setPresetNameNative},
- {"groupSetPresetNameNative", "(IILjava/lang/String;)V",
- (void*)groupSetPresetNameNative},
-};
-
-int register_com_android_bluetooth_hap_client(JNIEnv* env) {
- return jniRegisterNativeMethods(
- env, "com/android/bluetooth/hap/HapClientNativeInterface", sMethods,
- NELEM(sMethods));
-}
-} // namespace android
diff --git a/res/drawable/ic_bluetooth_share_icon.xml b/res/drawable/ic_bluetooth_share_icon.xml
new file mode 100644
index 000000000..310323499
--- /dev/null
+++ b/res/drawable/ic_bluetooth_share_icon.xml
@@ -0,0 +1,28 @@
+<!--
+ ~ Copyright (C) 2023 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.
+ -->
+<!-- This drawable should only be used by the Bluetooth application for its share target icon. -->
+<!-- The tint color is from https://www.bluetooth.com/develop-with-bluetooth/marketing-branding/ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="#2285F8">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L11,14.41V22h1l5.71-5.71L13.41,12L17.71,7.71z M13,5.83 l1.88,1.88L13,9.59V5.83z M14.88,16.29L13,18.17v-3.76L14.88,16.29z" />
+</vector>
diff --git a/res/mipmap-anydpi/bt_share.xml b/res/mipmap-anydpi/bt_share.xml
index c99e5609e..0a2dc9490 100644
--- a/res/mipmap-anydpi/bt_share.xml
+++ b/res/mipmap-anydpi/bt_share.xml
@@ -16,7 +16,7 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground>
<inset
- android:drawable="@*android:drawable/ic_bluetooth_share_icon"
+ android:drawable="@drawable/ic_bluetooth_share_icon"
android:insetTop="25%"
android:insetRight="25%"
android:insetBottom="25%"
diff --git a/res/values/config.xml b/res/values/config.xml
index bbf3e6ccb..868cb7e42 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -72,7 +72,6 @@
<bool name="profile_supported_broadcast">true</bool>
<bool name="profile_supported_hid_device">true</bool>
<bool name="profile_supported_le_audio">true</bool>
- <bool name="profile_supported_hap_client">true</bool>
<bool name="profile_supported_ba">false</bool>
<bool name="profile_supported_group_client">true</bool>
<bool name="profile_supported_csip_set_coordinator">true</bool>
diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java
index 4d16ba68e..be36bf2d7 100644
--- a/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -12,10 +12,6 @@
* 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.
- *
- * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
- * SPDX-License-Identifier: BSD-3-Clause-Clear
*/
package com.android.bluetooth.a2dp;
@@ -79,7 +75,6 @@ import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.lang.reflect.Method;
/**
* Provides Bluetooth A2DP profile, as a service in the Bluetooth application.
@@ -134,8 +129,6 @@ public class A2dpService extends ProfileService {
private boolean mIsTwsPlusEnabled = false;
private boolean mIsTwsPlusMonoSupported = false;
private boolean mShoActive = false;
- private boolean mGamingEnabled = false;
- private boolean mAlsDisabled;
private String mTwsPlusChannelMode = "dual-mono";
private BluetoothDevice mDummyDevice = null;
private static final int max_tws_connection = 2;
@@ -149,8 +142,6 @@ public class A2dpService extends ProfileService {
private static final int SET_EBMONO_CFG = 1;
private static final int SET_EBDUALMONO_CFG = 2;
- private static final int ENABLE_GAMING_MODE = 3;
- private static final int DISABLE_GAMING_MODE = 4;
private static final int MonoCfg_Timeout = 3000;
private static final int DualMonoCfg_Timeout = 3000;
@@ -176,14 +167,6 @@ public class A2dpService extends ProfileService {
}
mTwsPlusChannelMode = "dual-mono";
break;
- case ENABLE_GAMING_MODE:
- Log.d(TAG, "Enable Gaming Mode in A2DP!!");
- enableGamingModeinA2DP();
- break;
- case DISABLE_GAMING_MODE:
- Log.d(TAG, "Disable Gaming Mode in A2DP!!");
- disableGamingModeinA2DP();
- break;
default:
break;
}
@@ -261,8 +244,6 @@ public class A2dpService extends ProfileService {
if (!TwsPlusChannelMode.isEmpty() && "mono".equals(TwsPlusChannelMode)) {
mTwsPlusChannelMode = "mono";
}
- mAlsDisabled = SystemProperties.getBoolean
- ("persist.vendor.service.bt.als_disabled", false);
Log.d(TAG, "Default TwsPlus ChannelMode: " + mTwsPlusChannelMode);
}
@@ -1220,93 +1201,6 @@ public class A2dpService extends ProfileService {
return true;
}
- public void setGamingMode(BluetoothDevice device, boolean status) {
- if (status) {
- Log.v(TAG,"setGamingMode");
- Message msg = mHandler.obtainMessage(ENABLE_GAMING_MODE);
- mHandler.sendMessage(msg);
- }
- else {
- Log.v(TAG,"setGamingMode");
- Message msg = mHandler.obtainMessage(DISABLE_GAMING_MODE);
- mHandler.sendMessage(msg);
- }
- }
-
- private void enableGamingModeinA2DP() {
- if (mGamingEnabled) {
- Log.v(TAG,"enableGamingModeinA2DP: Already enabled Gaming Mode");
- return;
- }
- Log.v(TAG,"enableGamingModeinA2DP");
- BluetoothDevice device = getActiveDevice();
- BluetoothCodecStatus codecStatus = getCodecStatus(device);
- if (codecStatus == null) {
- Log.v(TAG,"enableGamingModeinA2DP: CodecStatus is empty");
- return;
- }
- BluetoothCodecConfig codecConfig = codecStatus.getCodecConfig();
- if (codecConfig == null) {
- Log.v(TAG,"enableGamingModeinA2DP: CodecConfig is empty");
- return;
- }
- if (codecConfig.getCodecType() == BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE) {
- Log.v(TAG,"APTX ADAPTIVE Codec Type");
- BluetoothCodecConfig a2dpGamingConfig =
- new BluetoothCodecConfig.Builder()
- .setCodecType(codecConfig.getCodecType())
- .setCodecPriority(codecConfig.getCodecPriority())
- .setSampleRate(codecConfig.getSampleRate())
- .setBitsPerSample(codecConfig.getBitsPerSample())
- .setChannelMode(codecConfig.getChannelMode())
- .setCodecSpecific1(codecConfig.getCodecSpecific1())
- .setCodecSpecific2(codecConfig.getCodecSpecific2())
- .setCodecSpecific3(codecConfig.getCodecSpecific3())
- .setCodecSpecific4(APTX_LL)
- .build();
- mGamingEnabled = true;
- mA2dpCodecConfig.setCodecConfigPreference(device, codecStatus, a2dpGamingConfig);
- } else {
- Log.d(TAG,"CodecType is not AptX AD");
- return;
- }
- }
-
- private void disableGamingModeinA2DP() {
- if (!mGamingEnabled) {
- Log.v(TAG,"disableGamingModeinA2DP: Already disabled Gaming Mode");
- return;
- }
- Log.v(TAG,"disableGamingModeinA2DP");
- BluetoothDevice device = getActiveDevice();
- BluetoothCodecStatus codecStatus = getCodecStatus(device);
- if (codecStatus == null) {
- Log.v(TAG,"disableGamingModeinA2DP: CodecStatus is empty, resetting gaming mode");
- mGamingEnabled = false;
- return;
- }
- BluetoothCodecConfig codecConfig = codecStatus.getCodecConfig();
- if (codecConfig == null) {
- Log.v(TAG,"disableGamingModeinA2DP: CodecConfig is empty, resetting gaming mode");
- mGamingEnabled = false;
- return;
- }
- BluetoothCodecConfig a2dpGamingConfig =
- new BluetoothCodecConfig.Builder()
- .setCodecType(codecConfig.getCodecType())
- .setCodecPriority(codecConfig.getCodecPriority())
- .setSampleRate(codecConfig.getSampleRate())
- .setBitsPerSample(codecConfig.getBitsPerSample())
- .setChannelMode(codecConfig.getChannelMode())
- .setCodecSpecific1(codecConfig.getCodecSpecific1())
- .setCodecSpecific2(codecConfig.getCodecSpecific2())
- .setCodecSpecific3(codecConfig.getCodecSpecific3())
- .setCodecSpecific4(APTX_HQ)
- .build();
- mGamingEnabled = false;
- mA2dpCodecConfig.setCodecConfigPreference(device, codecStatus, a2dpGamingConfig);
- }
-
private boolean setActiveDeviceA2dp(BluetoothDevice device) {
BluetoothCodecStatus codecStatus = null;
BluetoothDevice previousActiveDevice = mActiveDevice;
@@ -1699,46 +1593,6 @@ public class A2dpService extends ProfileService {
long cs4 = codecConfig.getCodecSpecific4();
GattService mGattService = GattService.getGattService();
- boolean isLowLatencyModeEnabled = false;
- Object objStreamAudioService = null;
-
- if (mAlsDisabled) {
- if (cs4 > 0 && codecConfig.getCodecType() ==
- BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE) {
- Log.e(TAG, "setCodecConfigPreference: ALS trigger is ignored");
- return;
- }
- }
-
- try {
- Class streamAudioService = Class.forName("com.android.bluetooth.apm.StreamAudioService");
- Method method = streamAudioService.getDeclaredMethod("getStreamAudioService");
- objStreamAudioService = method.invoke(null);
- if (objStreamAudioService != null) {
- Log.d(TAG, " setCodecConfigPreference, objStreamAudioService not null:");
- } else {
- Log.d(TAG, " setCodecConfigPreference, objStreamAudioService is null:");
- }
- } catch (Exception ex) {
- Log.w(TAG, ex);
- }
- try {
- Class streamAudioService = Class.forName("com.android.bluetooth.apm.StreamAudioService");
- Method method = streamAudioService.getDeclaredMethod("isLowLatencyModeEnabled");
- if (objStreamAudioService != null) {
- Log.d(TAG, " setCodecConfigPreference, invoke isLowLatencyModeEnabled");
- isLowLatencyModeEnabled = (boolean) method.invoke(objStreamAudioService);
- }
- Log.d(TAG, " setCodecConfigPreference, isLowLatencyModeEnabled:"
- + isLowLatencyModeEnabled);
- } catch (Exception ex) {
- Log.w(TAG, ex);
- }
-
- if (cs4 > 0 && isLowLatencyModeEnabled) {
- Log.e(TAG, "setCodecConfigPreference: LowLatencyModeEnabled, return");
- return;
- }
if(cs4 > 0 && mGattService != null) {
switch((int)(cs4 & APTX_MODE_MASK)) {
@@ -1758,28 +1612,6 @@ public class A2dpService extends ProfileService {
}
}
- if (cs4 > 0 && Utils.isDualModeAudioEnabled()) {
- MediaAudioIntf mMediaAudio = MediaAudioIntf.get();
- if(mMediaAudio == null) {
- return;
- }
-
- switch((int)(cs4 & APTX_MODE_MASK)) {
- case APTX_HQ:
- Log.d(TAG, "setCodecConfigPreference: disable Gaming from ALS");
- mMediaAudio.disableGamingMode(device, 0);
- break;
-
- case APTX_LL:
- Log.d(TAG, "setCodecConfigPreference: enable Gaming from ALS");
- mMediaAudio.enableGamingMode(device, 0);
- break;
- default:
- break;
- }
- return;
- }
-
if (codecConfig == null) {
Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
return;
@@ -1805,47 +1637,6 @@ public class A2dpService extends ProfileService {
+ Objects.toString(codecConfig));
}
long cs4 = codecConfig.getCodecSpecific4();
- boolean isLowLatencyModeEnabled = false;
- Object objStreamAudioService = null;
-
- if (mAlsDisabled) {
- if (cs4 > 0 && codecConfig.getCodecType() ==
- BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE) {
- Log.e(TAG, "setCodecConfigPreferenceA2dp: ALS trigger is ignored");
- return;
- }
- }
-
- try {
- Class streamAudioService = Class.forName("com.android.bluetooth.apm.StreamAudioService");
- Method method = streamAudioService.getDeclaredMethod("getStreamAudioService");
- objStreamAudioService = method.invoke(null);
- if (objStreamAudioService != null) {
- Log.d(TAG, " setCodecConfigPreferenceA2dp, objStreamAudioService not null:");
- } else {
- Log.d(TAG, " setCodecConfigPreferenceA2dp, objStreamAudioService is null:");
- }
- } catch (Exception ex) {
- Log.w(TAG, ex);
- }
- try {
- Class streamAudioService = Class.forName("com.android.bluetooth.apm.StreamAudioService");
- Method method = streamAudioService.getDeclaredMethod("isLowLatencyModeEnabled");
- if (objStreamAudioService != null) {
- Log.d(TAG, " setCodecConfigPreferenceA2dp, invoke isLowLatencyModeEnabled");
- isLowLatencyModeEnabled = (boolean) method.invoke(objStreamAudioService);
- }
- Log.d(TAG, "setCodecConfigPreferenceA2dp: isLowLatencyModeEnabled:"
- + isLowLatencyModeEnabled);
- } catch (Exception ex) {
- Log.w(TAG, ex);
- }
-
- if (cs4 > 0 && isLowLatencyModeEnabled) {
- Log.e(TAG, "setCodecConfigPreferenceA2dp: LowLatencyModeEnabled, return");
- return;
- }
-
GattService mGattService = GattService.getGattService();
if(cs4 > 0 && mGattService != null) {
switch((int)(cs4 & APTX_MODE_MASK)) {
@@ -3024,9 +2815,6 @@ public class A2dpService extends ProfileService {
public void updateStreamState(BluetoothDevice device, int streamStatus) {
MediaAudioIntf mMediaAudio = MediaAudioIntf.get();
mMediaAudio.onStreamStateChange(device, streamStatus);
- if (streamStatus == BluetoothA2dp.STATE_NOT_PLAYING) {
- disableGamingModeinA2DP();
- }
}
@Override
diff --git a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
index 22dcf0189..c987ca94b 100644
--- a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
+++ b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
@@ -12,10 +12,6 @@
* 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.
- *
- * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
- * SPDX-License-Identifier: BSD-3-Clause-Clear
*/
/**
@@ -77,7 +73,6 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.Scanner;
-import java.lang.reflect.Method;
import android.os.SystemProperties;
import com.android.bluetooth.btservice.AdapterService;
@@ -636,7 +631,6 @@ final class A2dpStateMachine extends StateMachine {
mA2dpService.setAvrcpAudioState(BluetoothA2dp.STATE_NOT_PLAYING, mDevice);
broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING,
BluetoothA2dp.STATE_PLAYING);
- mA2dpService.setGamingMode(mDevice, false);
}
}
break;
@@ -684,7 +678,6 @@ final class A2dpStateMachine extends StateMachine {
// Split A2dp will be enabled by default
boolean isSplitA2dpEnabled = true;
AdapterService adapterService = AdapterService.getAdapterService();
- Object objStreamAudioService = null;
if (adapterService != null){
isSplitA2dpEnabled = adapterService.isSplitA2dpEnabled();
@@ -760,34 +753,6 @@ final class A2dpStateMachine extends StateMachine {
Log.d(TAG, " mCodecConfigUpdated is false, codecConfigUpdated is required");
update = true;
}
-
- if ((newCodecConfig.getCodecType()
- == BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE)) {
- Log.d(TAG, "processCodecConfigEvent, APTX ADAPTIVE: reset Low Latency mode ");
- try {
- Class streamAudioService = Class.forName("com.android.bluetooth.apm.StreamAudioService");
- Method method = streamAudioService.getDeclaredMethod("getStreamAudioService");
- objStreamAudioService = method.invoke(null);
- if (objStreamAudioService != null) {
- Log.d(TAG, " processCodecConfigEvent, objStreamAudioService not null:");
- } else {
- Log.d(TAG, " processCodecConfigEvent, objStreamAudioService is null:");
- }
- } catch (Exception ex) {
- Log.w(TAG, ex);
- }
- try {
- Class streamAudioService =
- Class.forName("com.android.bluetooth.apm.StreamAudioService");
- Method method = streamAudioService.getDeclaredMethod("resetLowLatencyMode");
- if (objStreamAudioService != null) {
- Log.d(TAG, " processCodecConfigEvent, invoke resetLowLatencyMode ");
- method.invoke(objStreamAudioService);
- }
- } catch (Exception ex) {
- Log.w(TAG, ex);
- }
- }
Log.d(TAG, " update: " + update);
if (update) {
mA2dpService.codecConfigUpdated(mDevice, mCodecStatus, false);
@@ -851,9 +816,8 @@ final class A2dpStateMachine extends StateMachine {
log("A2DP Playing state : device: " + mDevice + " State:" + audioStateToString(prevState)
+ "->" + audioStateToString(newState));
- mA2dpService.updateStreamState(mDevice, newState);
-
- if(mA2dpService.isQtiLeAudioEnabled()) {
+ if (mA2dpService.isQtiLeAudioEnabled()) {
+ mA2dpService.updateStreamState(mDevice, newState);
return;
}
diff --git a/src/com/android/bluetooth/acm/AcmServIntf.java b/src/com/android/bluetooth/acm/AcmServIntf.java
index 9fc13f9ba..afcfd85d8 100644
--- a/src/com/android/bluetooth/acm/AcmServIntf.java
+++ b/src/com/android/bluetooth/acm/AcmServIntf.java
@@ -349,27 +349,6 @@ public class AcmServIntf {
return false;
}
- public boolean isAcmPlayingVoice(BluetoothDevice device) {
- if(AcmService == null)
- return false;
-
- Class[] arg = new Class[1];
- arg[0] = BluetoothDevice.class;
-
- try {
- Method isAcmPlayingVoice = AcmService.getDeclaredMethod("isAcmPlayingVoice", arg);
- boolean ret = (boolean)isAcmPlayingVoice.invoke(mAcmService, device);
- return ret;
- } catch(IllegalAccessException e) {
- Log.i(TAG, "Exception" + e);
- } catch(NoSuchMethodException e) {
- Log.i(TAG, "Exception" + e);
- } catch(InvocationTargetException e) {
- Log.i(TAG, "Exception" + e);
- }
- return false;
- }
-
/*
public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) {
if(AcmService == null)
diff --git a/src/com/android/bluetooth/apm/CallAudioIntf.java b/src/com/android/bluetooth/apm/CallAudioIntf.java
index fd862b727..bf01ec040 100644
--- a/src/com/android/bluetooth/apm/CallAudioIntf.java
+++ b/src/com/android/bluetooth/apm/CallAudioIntf.java
@@ -25,11 +25,6 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- *
**************************************************************************/
package com.android.bluetooth.apm;
@@ -403,24 +398,6 @@ public class CallAudioIntf {
return false;
}
- public boolean isVoipLeaWarEnabled() {
- if(CallAudio == null)
- return false;
-
- try {
- Method isVoipLeaWarEnabled = CallAudio.getDeclaredMethod("isVoipLeaWarEnabled");
- Boolean ret = (Boolean)isVoipLeaWarEnabled.invoke(mCallAudio);
- return ret;
- } catch(IllegalAccessException e) {
- Log.i(TAG, "Exception" + e);
- } catch(NoSuchMethodException e) {
- Log.i(TAG, "Exception" + e);
- } catch(InvocationTargetException e) {
- Log.i(TAG, "Exception" + e);
- }
- return false;
- }
-
public List<BluetoothDevice> getConnectedDevices() {
ArrayList<BluetoothDevice> devices = new ArrayList<>();
if(CallAudio == null)
diff --git a/src/com/android/bluetooth/apm/MediaAudioIntf.java b/src/com/android/bluetooth/apm/MediaAudioIntf.java
index 36063238c..aa6bc7648 100644
--- a/src/com/android/bluetooth/apm/MediaAudioIntf.java
+++ b/src/com/android/bluetooth/apm/MediaAudioIntf.java
@@ -381,46 +381,6 @@ public class MediaAudioIntf {
}
}
- public void enableGamingMode(BluetoothDevice device, int context) {
- if(MediaAudio == null)
- return;
-
- Class[] arg = new Class[2];
- arg[0] = BluetoothDevice.class;
- arg[1] = Integer.class;
-
- try {
- Method enableGamingMode = MediaAudio.getDeclaredMethod("enableGamingMode", arg);
- enableGamingMode.invoke(mMediaAudio, device, context);
- } catch(IllegalAccessException e) {
- Log.i(TAG, "Exception" + e);
- } catch(NoSuchMethodException e) {
- Log.i(TAG, "Exception" + e);
- } catch(InvocationTargetException e) {
- Log.i(TAG, "Exception" + e);
- }
- }
-
- public void disableGamingMode(BluetoothDevice device, int context) {
- if(MediaAudio == null)
- return;
-
- Class[] arg = new Class[2];
- arg[0] = BluetoothDevice.class;
- arg[1] = Integer.class;
-
- try {
- Method disableGamingMode = MediaAudio.getDeclaredMethod("disableGamingMode", arg);
- disableGamingMode.invoke(mMediaAudio, device, context);
- } catch(IllegalAccessException e) {
- Log.i(TAG, "Exception" + e);
- } catch(NoSuchMethodException e) {
- Log.i(TAG, "Exception" + e);
- } catch(InvocationTargetException e) {
- Log.i(TAG, "Exception" + e);
- }
- }
-
public void setLeAudioCodecConfigPreference(int groupId,
BluetoothLeAudioCodecConfig inputCodecConfig,
BluetoothLeAudioCodecConfig outputCodecConfig) {
diff --git a/src/com/android/bluetooth/btservice/ActiveDeviceManager.java b/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
index 821fb3399..edb4331db 100644
--- a/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
+++ b/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
@@ -42,12 +42,9 @@ import android.os.UserHandle;
import android.util.Log;
import com.android.bluetooth.a2dp.A2dpService;
-import com.android.bluetooth.apm.ApmConst;
import com.android.bluetooth.apm.ApmConstIntf;
import com.android.bluetooth.apm.ActiveDeviceManagerServiceIntf;
import com.android.bluetooth.apm.CallAudioIntf;
-import com.android.bluetooth.cc.CCService;
-import com.android.bluetooth.acm.AcmService;
import com.android.bluetooth.hearingaid.HearingAidService;
import com.android.bluetooth.hfp.HeadsetService;
@@ -148,14 +145,12 @@ public class ActiveDeviceManager {
private final List<BluetoothDevice> mA2dpConnectedDevices = new LinkedList<>();
private final List<BluetoothDevice> mHfpConnectedDevices = new LinkedList<>();
- private BluetoothDevice mSetRecentPendingA2dpActiveDevice = null;
private BluetoothDevice mA2dpActiveDevice = null;
private BluetoothDevice mHfpActiveDevice = null;
private BluetoothDevice mHearingAidActiveDevice = null;
private BluetoothDevice mLeAudioActiveDevice = null;
private boolean mTwsPlusSwitch = false;
private boolean mWiredDeviceConnected = false;
- private boolean mIsRecentPendingA2dpActiveDevice = false;
private static final int DELAY_A2DP_SLEEP_MILLIS = 50;
@@ -434,43 +429,14 @@ public class ActiveDeviceManager {
}
mA2dpConnectedDevices.add(device);
-
- CallAudioIntf mCallAudio = CallAudioIntf.get();
-
- int mCallActiveProfile =
- getCurrentActiveProfile(ApmConstIntf.AudioFeatures.CALL_AUDIO);
-
- ActiveDeviceManagerServiceIntf activeDeviceManager =
- ActiveDeviceManagerServiceIntf.get();
- BluetoothDevice mVoiceActiveDevice = null;
- AcmService acmService = AcmService.getAcmService();
- if (activeDeviceManager != null) {
- mVoiceActiveDevice =
- activeDeviceManager.getActiveDevice(ApmConstIntf.AudioFeatures.CALL_AUDIO);
- }
- Log.d(TAG, "mCallActiveProfile: " + mCallActiveProfile +
- ", mVoiceActiveDevice: " + mVoiceActiveDevice);
-
if (mHearingAidActiveDevice == null) {
- if ((mCallActiveProfile == ApmConst.AudioProfiles.BAP_CALL) &&
- acmService != null && acmService.isAcmPlayingVoice(mVoiceActiveDevice)) {
- Log.d(TAG, "BAP_Call streaming is on-going, cache a2dp active");
- setPendingA2dpActiveDevice(device);
- } else {
- // New connected device: select it as active
- setA2dpActiveDevice(device);
- }
+ // New connected device: select it as active
+ setA2dpActiveDevice(device);
break;
} else {
if (!ApmConstIntf.getQtiLeAudioEnabled()) {
- setHearingAidActiveDevice(null);
- if ((mCallActiveProfile == ApmConst.AudioProfiles.BAP_CALL) &&
- acmService != null && acmService.isAcmPlayingVoice(mVoiceActiveDevice)) {
- Log.d(TAG, "aosp lea, BAP_Call streaming is on-going, cache a2dp active");
- setPendingA2dpActiveDevice(device);
- } else {
- setA2dpActiveDevice(device);
- }
+ setHearingAidActiveDevice(null);
+ setA2dpActiveDevice(device);
}
}
break;
@@ -904,7 +870,6 @@ public class ActiveDeviceManager {
Log.d(TAG, "LEA device is source : " + bleDeviceInfo.isSource());
mWiredDeviceConnected = false;
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- boolean isDuMoEnabled = Utils.isDualModeAudioEnabled();
BluetoothDevice dev = adapter.getRemoteDevice(bleDeviceInfo.getAddress());
ActiveDeviceManagerServiceIntf activeDeviceManager =
ActiveDeviceManagerServiceIntf.get();
@@ -915,16 +880,11 @@ public class ActiveDeviceManager {
activeDeviceManager.getActiveDevice(ApmConstIntf.AudioFeatures.CALL_AUDIO);
Log.d(TAG, "LEA active dev: " + dev + ", absolute device:" + AbsDevice);
Log.d(TAG, "current active dev:" + activeDevice);
- if ((Objects.equals(dev,activeDevice) && bleDeviceInfo.isSource()) ||
- (isDuMoEnabled && (Objects.equals(dev,AbsDevice) && bleDeviceInfo.isSource()))) {
+ if (Objects.equals(dev,activeDevice) && bleDeviceInfo.isSource()) {
Log.d(TAG, "broadcast LEA device address: " + activeDevice);
broadcastLeActiveDeviceChange(AbsDevice);
onLeActiveDeviceChange(AbsDevice);
mLeAudioActiveDevice = AbsDevice;
- CCService ccService = CCService.getCCService();
- if (ccService != null) {
- ccService.handleAnswerCall(AbsDevice);
- }
}
}
}
@@ -1129,42 +1089,6 @@ public class ActiveDeviceManager {
}
}
- private void setPendingA2dpActiveDevice(BluetoothDevice device) {
- if (DBG) {
- Log.d(TAG, "setPendingA2dpActiveDevice(" + device + ")");
- }
- mIsRecentPendingA2dpActiveDevice = true;
- mSetRecentPendingA2dpActiveDevice = device;
- }
-
- public void resetPendingA2dpActiveDevice() {
- if (DBG) {
- Log.d(TAG, "resetPendingA2dpActiveDevice(): " +
- "mIsRecentPendingA2dpActiveDevice: " + mIsRecentPendingA2dpActiveDevice +
- " mSetRecentPendingA2dpActiveDevice: " + mSetRecentPendingA2dpActiveDevice);
- }
- if (mIsRecentPendingA2dpActiveDevice) {
- mIsRecentPendingA2dpActiveDevice = false;
- }
- if (mSetRecentPendingA2dpActiveDevice != null) {
- mSetRecentPendingA2dpActiveDevice = null;
- }
- }
-
- public void triggerPendingA2dpActiveDevice() {
- if (DBG) {
- Log.d(TAG, "triggerPendingA2dpActiveDevice(): " +
- "mIsRecentPendingA2dpActiveDevice: " + mIsRecentPendingA2dpActiveDevice +
- " mSetRecentPendingA2dpActiveDevice: " + mSetRecentPendingA2dpActiveDevice);
- }
- if (mIsRecentPendingA2dpActiveDevice &&
- mSetRecentPendingA2dpActiveDevice != null) {
- setA2dpActiveDevice(mSetRecentPendingA2dpActiveDevice);
- mIsRecentPendingA2dpActiveDevice = false;
- mSetRecentPendingA2dpActiveDevice = null;
- }
- }
-
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private boolean setLeAudioActiveDevice(BluetoothDevice device) {
if (DBG) {
@@ -1200,7 +1124,6 @@ public class ActiveDeviceManager {
private void resetState() {
mA2dpConnectedDevices.clear();
mA2dpActiveDevice = null;
- resetPendingA2dpActiveDevice();
mHfpConnectedDevices.clear();
mHfpActiveDevice = null;
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index 9cf114439..d239515cb 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -89,11 +89,6 @@
* Changes from Qualcomm Innovation Center are provided under the following license:
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
- *
- * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- *
*/
package com.android.bluetooth.btservice;
@@ -192,7 +187,6 @@ import android.util.Log;
import android.util.SparseArray;
import com.android.bluetooth.le_audio.LeAudioService;
-import com.android.bluetooth.hap.HapClientService;
import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.Utils;
@@ -438,7 +432,6 @@ public class AdapterService extends Service {
private SapService mSapService;
private GattService mGattService;
private LeAudioService mLeAudioService;
- private HapClientService mHapClientService;
private BassClientService mBassClientService;
///*_REF
@@ -1475,10 +1468,6 @@ public class AdapterService extends Service {
Log.e(TAG, "isSupported: profile: " + profile);
return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.LE_AUDIO);
}
- if (profile == BluetoothProfile.HAP_CLIENT) {
- Log.e(TAG, "isSupported: profile: " + profile);
- return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HAS);
- }
if (profile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) {
return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.BASS);
}
@@ -1553,12 +1542,6 @@ public class AdapterService extends Service {
Log.i(TAG, "isAnyProfileEnabled: LE_AUDIO profile enabled");
return true;
}
- if (!isQtiLeAudioEnabled &&
- mHapClientService != null && mHapClientService.getConnectionPolicy(device)
- > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
- Log.i(TAG, "isAnyProfileEnabled: HAP profile enabled");
- return true;
- }
if (mBassClientService != null && mBassClientService.getConnectionPolicy(device)
> BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
return true;
@@ -1702,16 +1685,9 @@ public class AdapterService extends Service {
BluetoothProfile.LE_AUDIO, device)
&& mLeAudioService.getConnectionPolicy(device)
> BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
- Log.i(TAG, "connectEnabledProfiles: Connecting LeAudio and HAP profile (BAP)");
+ Log.i(TAG, "connectEnabledProfiles: Connecting LeAudio profile (BAP)");
mLeAudioService.connect(device);
}
- if (mHapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
- BluetoothProfile.HAP_CLIENT, device)
- && mHapClientService.getConnectionPolicy(device)
- > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
- Log.i(TAG, "connectEnabledProfiles: Connecting HAP profile ");
- mHapClientService.connect(device);
- }
if (mBassClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, device)
&& mBassClientService.getConnectionPolicy(device)
@@ -1803,7 +1779,6 @@ public class AdapterService extends Service {
mSapService = SapService.getSapService();
mGattService = GattService.getGattService();
mLeAudioService = LeAudioService.getLeAudioService();
- mHapClientService = HapClientService.getHapClientService();
mVolumeControlService = VolumeControlService.getVolumeControlService();
if (isAdvBCAAudioFeatEnabled()) {
///*_REF
@@ -1948,13 +1923,6 @@ public class AdapterService extends Service {
return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
}
- public int isHapClientSupported() {
- if (BluetoothProperties.isProfileHapClientEnabled().orElse(false)) {
- return BluetoothStatusCodes.FEATURE_SUPPORTED;
- }
- return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
- }
-
public int isLeAudioBroadcastSourcePropertySet() {
if (BluetoothProperties.isProfileBapBroadcastSourceEnabled().orElse(false)) {
Log.e(TAG, "isLeAudioBroadcastSourceSupported: supported");
@@ -5440,30 +5408,6 @@ public class AdapterService extends Service {
return info.callerPackageName;
}
- public boolean handleLeSetActiveDevice(BluetoothDevice device) {
- boolean isAospLeaEnabled = ApmConstIntf.getAospLeaEnabled();
- boolean isLeActiveDevice = false;
- Log.i(TAG, "handleLeSetActiveDevice: isAospLeaEnabled: "
- + isAospLeaEnabled + ", device: " + device);
- for (BluetoothDevice dev : getActiveDevices(BluetoothProfile.LE_AUDIO)) {
- if (dev != null) {
- Log.i(TAG, "handleLeSetActiveDevice: LE audio device is active");
- isLeActiveDevice = true;
- break;
- }
- }
-
- if (isAospLeaEnabled &&
- mLeAudioService != null && (device == null && isLeActiveDevice
- || mLeAudioService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
- Log.i(TAG, "handleLeSetActiveDevice: Setting active Le Audio device " + device);
- mLeAudioService.setActiveDevice(device);
- return true;
- }
- return false;
- }
-
/**
* Sets device as the active devices for the profiles passed into the function
*
@@ -5502,10 +5446,22 @@ public class AdapterService extends Service {
return false;
}
- boolean isLeActiveDeviceHandled = false;
- isLeActiveDeviceHandled = handleLeSetActiveDevice(device);
- if (isLeActiveDeviceHandled) {
- Log.i(TAG, "setActiveDevice: LE audio device made active");
+ boolean isLeAudioDeviceActive = false;
+ for (BluetoothDevice dev : getActiveDevices(BluetoothProfile.LE_AUDIO)) {
+ if (dev != null) {
+ Log.i(TAG, "setActiveDevice: LE audio device is active");
+ isLeAudioDeviceActive = true;
+ break;
+ }
+ }
+
+ //Make only Le-A device setactive when qti LE-A not enabled.
+ if (!isQtiLeAudioEnabled &&
+ mLeAudioService != null && (device == null && isLeAudioDeviceActive
+ || mLeAudioService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
+ Log.i(TAG, "setActiveDevice: Setting active Le Audio device " + device);
+ mLeAudioService.setActiveDeviceBlocking(device);
return true;
}
@@ -5528,17 +5484,13 @@ public class AdapterService extends Service {
if (setHeadset && mHeadsetService != null) {
if (isQtiLeAudioEnabled || isAospLeaEnabled) {
activeDeviceManager.setActiveDevice(device,
- ApmConstIntf.AudioFeatures.CALL_AUDIO, false);
+ ApmConstIntf.AudioFeatures.CALL_AUDIO, true);
} else {
Log.i(TAG, "setActiveDevice: Setting active Headset " + device);
mHeadsetService.setActiveDevice(device);
}
}
- if (device == null) {
- handleLeSetActiveDevice(device);
- }
-
return true;
}
@@ -5563,9 +5515,7 @@ public class AdapterService extends Service {
Log.e(TAG, "getActiveDevices: HeadsetService is null");
} else {
BluetoothDevice defaultValue = null;
- CallAudioIntf mCallAudio = CallAudioIntf.get();
- if (ApmConstIntf.getQtiLeAudioEnabled() ||
- (ApmConstIntf.getAospLeaEnabled() && mCallAudio.isVoipLeaWarEnabled())) {
+ if (ApmConstIntf.getQtiLeAudioEnabled()) {
Log.i(TAG, "getQtiLeAudioEnabled() is true, get HFP active dev from APM");
ActiveDeviceManagerServiceIntf activeDeviceManager =
ActiveDeviceManagerServiceIntf.get();
@@ -5666,14 +5616,6 @@ public class AdapterService extends Service {
numProfilesConnected++;
}
if (!isQtiLeAudioEnabled &&
- mHapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
- BluetoothProfile.HAP_CLIENT, device)) {
- Log.i(TAG, "connectAllEnabledProfiles: Connecting HAP");
- mHapClientService.setConnectionPolicy(device,
- BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- numProfilesConnected++;
- }
- if (!isQtiLeAudioEnabled &&
mLeAudioService != null && isSupported(localDeviceUuids, remoteDeviceUuids,
BluetoothProfile.LE_AUDIO, device)) {
Log.i(TAG, "connectAllEnabledProfiles: Connecting Le Audio");
@@ -5859,12 +5801,6 @@ public class AdapterService extends Service {
Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Le Audio");
mLeAudioService.disconnect(device);
}
- if (!isQtiLeAudioEnabled &&
- mHapClientService != null && mHapClientService.getConnectionState(device)
- == BluetoothProfile.STATE_CONNECTED) {
- Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting HAP");
- mHapClientService.disconnect(device);
- }
if (mA2dpSinkService != null && mA2dpSinkService.getConnectionState(device)
== BluetoothProfile.STATE_CONNECTED) {
Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp Sink");
diff --git a/src/com/android/bluetooth/btservice/Config.java b/src/com/android/bluetooth/btservice/Config.java
index 49f59ec5b..0e585bf6d 100644
--- a/src/com/android/bluetooth/btservice/Config.java
+++ b/src/com/android/bluetooth/btservice/Config.java
@@ -89,7 +89,6 @@ import com.android.bluetooth.sap.SapService;
import com.android.bluetooth.apm.ApmConstIntf;
import com.android.bluetooth.ba.BATService;
import com.android.bluetooth.le_audio.LeAudioService;
-import com.android.bluetooth.hap.HapClientService;
import com.android.bluetooth.vc.VolumeControlService;
import java.util.ArrayList;
@@ -234,9 +233,6 @@ public class Config {
R.bool.profile_supported_le_audio,
(1L << BluetoothProfile.LE_AUDIO |
1L << BluetoothProfile.LE_AUDIO_BROADCAST)),
- new ProfileConfig(HapClientService.class,
- R.bool.profile_supported_hap_client,
- (1L << BluetoothProfile.HAP_CLIENT)),
new ProfileConfig(VolumeControlService.class,
R.bool.profile_supported_volume_control,
(1L << BluetoothProfile.VOLUME_CONTROL))
@@ -535,16 +531,6 @@ public class Config {
}
Log.d(TAG, "LeAudioService profile mask: " + mask);
return mask;
- } else if (profile == HapClientService.class) {
- long mask = config.mMask;
- HapClientService hapClientService = HapClientService.getHapClientService();
- if (hapClientService != null) {
- if (hapClientService.isEnabled() == false) {
- mask &= ~(1L << BluetoothProfile.HAP_CLIENT);
- }
- }
- Log.d(TAG, "HapClientService profile mask: " + mask);
- return mask;
}
return config.mMask;
}
@@ -596,8 +582,6 @@ public class Config {
return addAospAudioProfiles(serviceName);
} if (serviceName.equals("VolumeControlService")) {
return VolumeControlService.isEnabled();
- } if (serviceName.equals("HapClientService")) {
- return addAospAudioProfiles(serviceName);
}
if ((serviceName.equals("HeadsetClientService")) && (!mIsHfpClient))
return false;
@@ -625,10 +609,6 @@ public class Config {
BluetoothStatusCodes.FEATURE_NOT_SUPPORTED) {
return false;
}
- if (serviceName.equals("HapClientService") && (adapterService.isHapClientSupported() ==
- BluetoothStatusCodes.FEATURE_NOT_SUPPORTED)) {
- return false;
- }
return true;
}
diff --git a/src/com/android/bluetooth/btservice/PhonePolicy.java b/src/com/android/bluetooth/btservice/PhonePolicy.java
index b2ce3f0c8..f75c98f6d 100644
--- a/src/com/android/bluetooth/btservice/PhonePolicy.java
+++ b/src/com/android/bluetooth/btservice/PhonePolicy.java
@@ -80,7 +80,6 @@ import android.os.SystemProperties;
import android.util.Log;
import com.android.bluetooth.le_audio.LeAudioService;
-import com.android.bluetooth.hap.HapClientService;
import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.a2dpsink.A2dpSinkService;
import com.android.bluetooth.apm.ApmConstIntf;
@@ -421,7 +420,7 @@ class PhonePolicy {
ParcelUuid.fromString("00006AD0-0000-1000-8000-00805F9B34FB");
ParcelUuid ADV_AUDIO_HEARINGAID =
- ParcelUuid.fromString("00001854-0000-1000-8000-00805F9B34FB");
+ ParcelUuid.fromString("00006AD2-0000-1000-8000-00805F9B34FB");
ParcelUuid ADV_AUDIO_P_MEDIA =
ParcelUuid.fromString("00006AD1-0000-1000-8000-00805F9B34FB");
@@ -449,7 +448,6 @@ class PhonePolicy {
PanService panService = mFactory.getPanService();
HearingAidService hearingAidService = mFactory.getHearingAidService();
LeAudioService leAudioService = mFactory.getLeAudioService();
- HapClientService hapClientService = mFactory.getHapClientService();
CsipSetCoordinatorService csipSetCooridnatorService =
mFactory.getCsipSetCoordinatorService();
VolumeControlService volumeControlService = mFactory.getVolumeControlService();
@@ -577,24 +575,6 @@ class PhonePolicy {
}
}
}
-
- if ((hapClientService != null) && ArrayUtils.contains(uuids,
- BluetoothUuid.HAS) && (hapClientService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) {
- debugLog("setting hearing access profile priority for device " + device);
- if ((hearingAidService != null) && ArrayUtils.contains(uuids,
- BluetoothUuid.HEARING_AID) && (hearingAidService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
- debugLog("LE Audio preferred over ASHA for device " + device);
- if (isLeAudioProfileAllowed) {
- mAdapterService.getDatabase().setProfileConnectionPolicy(device,
- BluetoothProfile.HEARING_AID, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
- }
- }
- mAdapterService.getDatabase().setProfileConnectionPolicy(device,
- BluetoothProfile.HAP_CLIENT, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- }
-
if ((bcService != null) && ArrayUtils.contains(uuids,
BluetoothUuid.BASS) && (bcService.getConnectionPolicy(device)
== BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) {
diff --git a/src/com/android/bluetooth/btservice/ServiceFactory.java b/src/com/android/bluetooth/btservice/ServiceFactory.java
index 34d8d5d32..96c83ac31 100644
--- a/src/com/android/bluetooth/btservice/ServiceFactory.java
+++ b/src/com/android/bluetooth/btservice/ServiceFactory.java
@@ -63,7 +63,6 @@ import com.android.bluetooth.hid.HidHostService;
import com.android.bluetooth.lebroadcast.BassClientService;
import com.android.bluetooth.pan.PanService;
import com.android.bluetooth.le_audio.LeAudioService;
-import com.android.bluetooth.hap.HapClientService;
import com.android.bluetooth.vc.VolumeControlService;
import android.util.Log;
@@ -119,10 +118,6 @@ public class ServiceFactory {
return LeAudioService.getLeAudioService();
}
- public HapClientService getHapClientService() {
- return HapClientService.getHapClientService();
- }
-
public BassClientService getBassClientService() {
return BassClientService.getBassClientService();
}
diff --git a/src/com/android/bluetooth/btservice/storage/Metadata.java b/src/com/android/bluetooth/btservice/storage/Metadata.java
index 67650656e..c07747760 100644
--- a/src/com/android/bluetooth/btservice/storage/Metadata.java
+++ b/src/com/android/bluetooth/btservice/storage/Metadata.java
@@ -173,9 +173,6 @@ class Metadata {
case BluetoothProfile.CSIP_SET_COORDINATOR:
profileConnectionPolicies.csip_set_coordinator_connection_policy = connectionPolicy;
break;
- case BluetoothProfile.HAP_CLIENT:
- profileConnectionPolicies.hap_client_connection_policy = connectionPolicy;
- break;
case BluetoothProfile.LE_AUDIO:
profileConnectionPolicies.le_audio_connection_policy = connectionPolicy;
break;
@@ -222,8 +219,6 @@ class Metadata {
return profileConnectionPolicies.csip_set_coordinator_connection_policy;
case BluetoothProfile.LE_AUDIO:
return profileConnectionPolicies.le_audio_connection_policy;
- case BluetoothProfile.HAP_CLIENT:
- return profileConnectionPolicies.hap_client_connection_policy;
case BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT:
return profileConnectionPolicies.bass_client_connection_policy;
case BluetoothProfile.VOLUME_CONTROL:
diff --git a/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java b/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java
index 2cdbfa774..7167099ed 100644
--- a/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java
+++ b/src/com/android/bluetooth/btservice/storage/ProfilePrioritiesEntity.java
@@ -72,7 +72,6 @@ class ProfilePrioritiesEntity {
public int map_client_connection_policy;
public int bc_profile_priority;
public int csip_set_coordinator_connection_policy;
- public int hap_client_connection_policy;
public int le_audio_connection_policy;
public int bass_client_connection_policy;
public int volume_control_connection_policy;
@@ -92,7 +91,6 @@ class ProfilePrioritiesEntity {
map_client_connection_policy = BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
bc_profile_priority = BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
csip_set_coordinator_connection_policy = BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
- hap_client_connection_policy = BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
le_audio_connection_policy = BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
bass_client_connection_policy = BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
volume_control_connection_policy = BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
@@ -114,7 +112,6 @@ class ProfilePrioritiesEntity {
.append("|SAP=").append(sap_connection_policy)
.append("|HEARING_AID=").append(hearing_aid_connection_policy)
.append("|LE_AUDIO=").append(le_audio_connection_policy)
- .append("|HAP=").append(hap_client_connection_policy)
.append("|LE_BROADCAST_ASSISTANT=").append(bass_client_connection_policy)
.append("|VOLUME_CONTROL=").append(volume_control_connection_policy);
diff --git a/src/com/android/bluetooth/hap/HapClientNativeInterface.java b/src/com/android/bluetooth/hap/HapClientNativeInterface.java
deleted file mode 100644
index 5fab43aef..000000000
--- a/src/com/android/bluetooth/hap/HapClientNativeInterface.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.bluetooth.hap;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHapPresetInfo;
-import android.util.Log;
-
-import com.android.bluetooth.Utils;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Hearing Access Profile Client Native Interface to/from JNI.
- */
-public class HapClientNativeInterface {
- private static final String TAG = "HapClientNativeInterface";
- private static final boolean DBG = true;
- private final BluetoothAdapter mAdapter;
-
- @GuardedBy("INSTANCE_LOCK")
- private static HapClientNativeInterface sInstance;
- private static final Object INSTANCE_LOCK = new Object();
-
- static {
- classInitNative();
- }
-
- private HapClientNativeInterface() {
- mAdapter = BluetoothAdapter.getDefaultAdapter();
- if (mAdapter == null) {
- Log.wtf(TAG, "No Bluetooth Adapter Available");
- }
- }
-
- /**
- * Get singleton instance.
- */
- public static HapClientNativeInterface getInstance() {
- synchronized (INSTANCE_LOCK) {
- if (sInstance == null) {
- sInstance = new HapClientNativeInterface();
- }
- return sInstance;
- }
- }
-
- /**
- * Initiates HapClientService connection to a remote device.
- *
- * @param device the remote device
- * @return true on success, otherwise false.
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public boolean connectHapClient(BluetoothDevice device) {
- return connectHapClientNative(getByteAddress(device));
- }
-
- /**
- * Disconnects HapClientService from a remote device.
- *
- * @param device the remote device
- * @return true on success, otherwise false.
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public boolean disconnectHapClient(BluetoothDevice device) {
- return disconnectHapClientNative(getByteAddress(device));
- }
-
- /**
- * Gets a HapClientService device
- *
- * @param address the remote device address
- * @return Bluetooth Device.
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public BluetoothDevice getDevice(byte[] address) {
- return mAdapter.getRemoteDevice(address);
- }
-
- private byte[] getByteAddress(BluetoothDevice device) {
- if (device == null) {
- return Utils.getBytesFromAddress("00:00:00:00:00:00");
- }
- return Utils.getBytesFromAddress(device.getAddress());
- }
-
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- void sendMessageToService(HapClientStackEvent event) {
- HapClientService service = HapClientService.getHapClientService();
- if (service != null) {
- service.messageFromNative(event);
- } else {
- Log.e(TAG, "Event ignored, service not available: " + event);
- }
- }
-
- /**
- * Initializes the native interface.
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void init() {
- initNative();
- }
-
- /**
- * Cleanup the native interface.
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void cleanup() {
- cleanupNative();
- }
-
- /**
- * Selects the currently active preset for a HA device
- *
- * @param device is the device for which we want to set the active preset
- * @param presetIndex is an index of one of the available presets
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void selectActivePreset(BluetoothDevice device, int presetIndex) {
- selectActivePresetNative(getByteAddress(device), presetIndex);
- }
-
- /**
- * Selects the currently active preset for a HA device group.
- *
- * @param groupId is the device group identifier for which want to set the active preset
- * @param presetIndex is an index of one of the available presets
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void groupSelectActivePreset(int groupId, int presetIndex) {
- groupSelectActivePresetNative(groupId, presetIndex);
- }
-
- /**
- * Sets the next preset as a currently active preset for a HA device
- *
- * @param device is the device for which we want to set the active preset
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void nextActivePreset(BluetoothDevice device) {
- nextActivePresetNative(getByteAddress(device));
- }
-
- /**
- * Sets the next preset as a currently active preset for a HA device group
- *
- * @param groupId is the device group identifier for which want to set the active preset
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void groupNextActivePreset(int groupId) {
- groupNextActivePresetNative(groupId);
- }
-
- /**
- * Sets the previous preset as a currently active preset for a HA device
- *
- * @param device is the device for which we want to set the active preset
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void previousActivePreset(BluetoothDevice device) {
- previousActivePresetNative(getByteAddress(device));
- }
-
- /**
- * Sets the previous preset as a currently active preset for a HA device group
- *
- * @param groupId is the device group identifier for which want to set the active preset
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void groupPreviousActivePreset(int groupId) {
- groupPreviousActivePresetNative(groupId);
- }
-
- /**
- * Requests the preset name
- *
- * @param device is the device for which we want to get the preset name
- * @param presetIndex is an index of one of the available presets
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void getPresetInfo(BluetoothDevice device, int presetIndex) {
- getPresetInfoNative(getByteAddress(device), presetIndex);
- }
-
- /**
- * Sets the preset name
- *
- * @param device is the device for which we want to get the preset name
- * @param presetIndex is an index of one of the available presets
- * @param name is a new name for a preset
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void setPresetName(BluetoothDevice device, int presetIndex, String name) {
- setPresetNameNative(getByteAddress(device), presetIndex, name);
- }
-
- /**
- * Sets the preset name
- *
- * @param groupId is the device group
- * @param presetIndex is an index of one of the available presets
- * @param name is a new name for a preset
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void groupSetPresetName(int groupId, int presetIndex, String name) {
- groupSetPresetNameNative(groupId, presetIndex, name);
- }
-
- // Callbacks from the native stack back into the Java framework.
- // All callbacks are routed via the Service which will disambiguate which
- // state machine the message should be routed to.
-
- @VisibleForTesting
- void onConnectionStateChanged(int state, byte[] address) {
- HapClientStackEvent event =
- new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- event.device = getDevice(address);
- event.valueInt1 = state;
-
- if (DBG) {
- Log.d(TAG, "onConnectionStateChanged: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onDeviceAvailable(byte[] address, int features) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE);
- event.device = getDevice(address);
- event.valueInt1 = features;
-
- if (DBG) {
- Log.d(TAG, "onDeviceAvailable: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onFeaturesUpdate(byte[] address, int features) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES);
- event.device = getDevice(address);
- event.valueInt1 = features;
-
- if (DBG) {
- Log.d(TAG, "onFeaturesUpdate: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onActivePresetSelected(byte[] address, int presetIndex) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED);
- event.device = getDevice(address);
- event.valueInt1 = presetIndex;
-
- if (DBG) {
- Log.d(TAG, "onActivePresetSelected: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onActivePresetGroupSelected(int groupId, int presetIndex) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED);
- event.valueInt1 = presetIndex;
- event.valueInt2 = groupId;
-
- if (DBG) {
- Log.d(TAG, "onActivePresetGroupSelected: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onActivePresetSelectError(byte[] address, int resultCode) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR);
- event.device = getDevice(address);
- event.valueInt1 = resultCode;
-
- if (DBG) {
- Log.d(TAG, "onActivePresetSelectError: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onActivePresetGroupSelectError(int groupId, int resultCode) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR);
- event.valueInt1 = resultCode;
- event.valueInt2 = groupId;
-
- if (DBG) {
- Log.d(TAG, "onActivePresetGroupSelectError: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onPresetInfo(byte[] address, int infoReason, BluetoothHapPresetInfo[] presets) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO);
- event.device = getDevice(address);
- event.valueInt2 = infoReason;
- event.valueList = new ArrayList<>(Arrays.asList(presets));
-
- if (DBG) {
- Log.d(TAG, "onPresetInfo: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onGroupPresetInfo(int groupId, int infoReason, BluetoothHapPresetInfo[] presets) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO);
- event.valueInt2 = infoReason;
- event.valueInt3 = groupId;
- event.valueList = new ArrayList<>(Arrays.asList(presets));
-
- if (DBG) {
- Log.d(TAG, "onPresetInfo: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onPresetNameSetError(byte[] address, int presetIndex, int resultCode) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR);
- event.device = getDevice(address);
- event.valueInt1 = resultCode;
- event.valueInt2 = presetIndex;
-
- if (DBG) {
- Log.d(TAG, "OnPresetNameSetError: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onGroupPresetNameSetError(int groupId, int presetIndex, int resultCode) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR);
- event.valueInt1 = resultCode;
- event.valueInt2 = presetIndex;
- event.valueInt3 = groupId;
-
- if (DBG) {
- Log.d(TAG, "OnPresetNameSetError: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onPresetInfoError(byte[] address, int presetIndex, int resultCode) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR);
- event.device = getDevice(address);
- event.valueInt1 = resultCode;
- event.valueInt2 = presetIndex;
-
- if (DBG) {
- Log.d(TAG, "onPresetInfoError: " + event);
- }
- sendMessageToService(event);
- }
-
- @VisibleForTesting
- void onGroupPresetInfoError(int groupId, int presetIndex, int resultCode) {
- HapClientStackEvent event = new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR);
- event.valueInt1 = resultCode;
- event.valueInt2 = presetIndex;
- event.valueInt3 = groupId;
-
- if (DBG) {
- Log.d(TAG, "onPresetInfoError: " + event);
- }
- sendMessageToService(event);
- }
-
- // Native methods that call into the JNI interface
- private static native void classInitNative();
- private native void initNative();
- private native void cleanupNative();
- private native boolean connectHapClientNative(byte[] address);
- private native boolean disconnectHapClientNative(byte[] address);
- private native void selectActivePresetNative(byte[] byteAddress, int presetIndex);
- private native void groupSelectActivePresetNative(int groupId, int presetIndex);
- private native void nextActivePresetNative(byte[] byteAddress);
- private native void groupNextActivePresetNative(int groupId);
- private native void previousActivePresetNative(byte[] byteAddress);
- private native void groupPreviousActivePresetNative(int groupId);
- private native void getPresetInfoNative(byte[] byteAddress, int presetIndex);
- private native void setPresetNameNative(byte[] byteAddress, int presetIndex, String name);
- private native void groupSetPresetNameNative(int groupId, int presetIndex, String name);
-}
diff --git a/src/com/android/bluetooth/hap/HapClientService.java b/src/com/android/bluetooth/hap/HapClientService.java
deleted file mode 100644
index 5d39558b6..000000000
--- a/src/com/android/bluetooth/hap/HapClientService.java
+++ /dev/null
@@ -1,1674 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.bluetooth.hap;
-
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
-
-import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;
-
-import android.annotation.Nullable;
-import android.bluetooth.BluetoothCsipSetCoordinator;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHapClient;
-import android.bluetooth.BluetoothHapPresetInfo;
-import android.bluetooth.BluetoothLeAudio;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothStatusCodes;
-import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothHapClient;
-import android.bluetooth.IBluetoothHapClientCallback;
-import android.content.AttributionSource;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.HandlerThread;
-import android.os.ParcelUuid;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.sysprop.BluetoothProperties;
-import android.util.Log;
-
-import com.android.bluetooth.Utils;
-import com.android.bluetooth.btservice.AdapterService;
-import com.android.bluetooth.btservice.ProfileService;
-import com.android.bluetooth.btservice.ServiceFactory;
-import com.android.bluetooth.btservice.storage.DatabaseManager;
-import com.android.bluetooth.csip.CsipSetCoordinatorService;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.modules.utils.SynchronousResultReceiver;
-
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Provides Bluetooth Hearing Access profile, as a service.
- * @hide
- */
-public class HapClientService extends ProfileService {
- private static final boolean DBG = true;
- private static final String TAG = "HapClientService";
-
- // Upper limit of all HearingAccess devices: Bonded or Connected
- private static final int MAX_HEARING_ACCESS_STATE_MACHINES = 10;
- private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
- private static HapClientService sHapClient;
- private final Map<BluetoothDevice, HapClientStateMachine> mStateMachines =
- new HashMap<>();
- @VisibleForTesting
- HapClientNativeInterface mHapClientNativeInterface;
- private AdapterService mAdapterService;
- private DatabaseManager mDatabaseManager;
- private HandlerThread mStateMachinesThread;
- private BroadcastReceiver mBondStateChangedReceiver;
- private BroadcastReceiver mConnectionStateChangedReceiver;
-
- private final Map<BluetoothDevice, Integer> mDeviceCurrentPresetMap = new HashMap<>();
- private final Map<BluetoothDevice, Integer> mDeviceFeaturesMap = new HashMap<>();
- private final Map<BluetoothDevice, List<BluetoothHapPresetInfo>> mPresetsMap =
- new HashMap<>();
-
- @VisibleForTesting
- RemoteCallbackList<IBluetoothHapClientCallback> mCallbacks;
-
- @VisibleForTesting
- ServiceFactory mFactory = new ServiceFactory();
-
- public static boolean isEnabled() {
- return BluetoothProperties.isProfileHapClientEnabled().orElse(false);
- }
-
- private static synchronized void setHapClient(HapClientService instance) {
- if (DBG) {
- Log.d(TAG, "setHapClient(): set to: " + instance);
- }
- sHapClient = instance;
- }
-
- /**
- * Get the HapClientService instance
- * @return HapClientService instance
- */
- public static synchronized HapClientService getHapClientService() {
- if (sHapClient == null) {
- Log.w(TAG, "getHapClientService(): service is NULL");
- return null;
- }
-
- if (!sHapClient.isAvailable()) {
- Log.w(TAG, "getHapClientService(): service is not available");
- return null;
- }
- return sHapClient;
- }
-
- @Override
- protected void create() {
- if (DBG) {
- Log.d(TAG, "create()");
- }
- }
-
- @Override
- protected void cleanup() {
- if (DBG) {
- Log.d(TAG, "cleanup()");
- }
- }
-
- @Override
- protected IProfileServiceBinder initBinder() {
- return new BluetoothHapClientBinder(this);
- }
-
- @Override
- protected boolean start() {
- if (DBG) {
- Log.d(TAG, "start()");
- }
-
- if (sHapClient != null) {
- throw new IllegalStateException("start() called twice");
- }
-
- // Get AdapterService, HapClientNativeInterface, DatabaseManager, AudioManager.
- // None of them can be null.
- mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(),
- "AdapterService cannot be null when HapClientService starts");
- mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(),
- "DatabaseManager cannot be null when HapClientService starts");
- mHapClientNativeInterface = Objects.requireNonNull(
- HapClientNativeInterface.getInstance(),
- "HapClientNativeInterface cannot be null when HapClientService starts");
-
- // Start handler thread for state machines
- mStateMachines.clear();
- mStateMachinesThread = new HandlerThread("HapClientService.StateMachines");
- mStateMachinesThread.start();
-
- // Setup broadcast receivers
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
- mBondStateChangedReceiver = new BondStateChangedReceiver();
- registerReceiver(mBondStateChangedReceiver, filter);
- filter = new IntentFilter();
- filter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
- mConnectionStateChangedReceiver = new ConnectionStateChangedReceiver();
- registerReceiver(mConnectionStateChangedReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
-
- mCallbacks = new RemoteCallbackList<IBluetoothHapClientCallback>();
-
- // Initialize native interface
- mHapClientNativeInterface.init();
-
- // Mark service as started
- setHapClient(this);
-
- return true;
- }
-
- @Override
- protected boolean stop() {
- if (DBG) {
- Log.d(TAG, "stop()");
- }
- if (sHapClient == null) {
- Log.w(TAG, "stop() called before start()");
- return true;
- }
-
- // Marks service as stopped
- setHapClient(null);
-
- // Unregister broadcast receivers
- unregisterReceiver(mBondStateChangedReceiver);
- mBondStateChangedReceiver = null;
- unregisterReceiver(mConnectionStateChangedReceiver);
- mConnectionStateChangedReceiver = null;
-
- // Destroy state machines and stop handler thread
- synchronized (mStateMachines) {
- for (HapClientStateMachine sm : mStateMachines.values()) {
- sm.doQuit();
- sm.cleanup();
- }
- mStateMachines.clear();
- }
-
- if (mStateMachinesThread != null) {
- try {
- mStateMachinesThread.quitSafely();
- mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
- mStateMachinesThread = null;
- } catch (InterruptedException e) {
- // Do not rethrow as we are shutting down anyway
- }
- }
-
- // Cleanup GATT interface
- mHapClientNativeInterface.cleanup();
- mHapClientNativeInterface = null;
-
- // Cleanup the internals
- mDeviceCurrentPresetMap.clear();
- mDeviceFeaturesMap.clear();
- mPresetsMap.clear();
-
- if (mCallbacks != null) {
- mCallbacks.kill();
- }
-
- // Clear AdapterService
- mAdapterService = null;
-
- return true;
- }
-
- @VisibleForTesting
- void bondStateChanged(BluetoothDevice device, int bondState) {
- if (DBG) {
- Log.d(TAG, "Bond state changed for device: " + device + " state: " + bondState);
- }
-
- // Remove state machine if the bonding for a device is removed
- if (bondState != BluetoothDevice.BOND_NONE) {
- return;
- }
-
- mDeviceCurrentPresetMap.remove(device);
- mDeviceFeaturesMap.remove(device);
- mPresetsMap.remove(device);
-
- synchronized (mStateMachines) {
- HapClientStateMachine sm = mStateMachines.get(device);
- if (sm == null) {
- return;
- }
- if (sm.getConnectionState() != BluetoothProfile.STATE_DISCONNECTED) {
- Log.i(TAG, "Disconnecting device because it was unbonded.");
- disconnect(device);
- return;
- }
- removeStateMachine(device);
- }
- }
-
- private void removeStateMachine(BluetoothDevice device) {
- synchronized (mStateMachines) {
- HapClientStateMachine sm = mStateMachines.get(device);
- if (sm == null) {
- Log.w(TAG, "removeStateMachine: device " + device
- + " does not have a state machine");
- return;
- }
- Log.i(TAG, "removeStateMachine: removing state machine for device: " + device);
- sm.doQuit();
- sm.cleanup();
- mStateMachines.remove(device);
- }
- }
-
- List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
- enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, "Need BLUETOOTH_CONNECT permission");
- ArrayList<BluetoothDevice> devices = new ArrayList<>();
- if (states == null) {
- return devices;
- }
- final BluetoothDevice[] bondedDevices = mAdapterService.getBondedDevices();
- if (bondedDevices == null) {
- return devices;
- }
- synchronized (mStateMachines) {
- for (BluetoothDevice device : bondedDevices) {
- final ParcelUuid[] featureUuids = device.getUuids();
- if (!Utils.arrayContains(featureUuids, BluetoothUuid.HAS)) {
- continue;
- }
- int connectionState = BluetoothProfile.STATE_DISCONNECTED;
- HapClientStateMachine sm = mStateMachines.get(device);
- if (sm != null) {
- connectionState = sm.getConnectionState();
- }
- for (int state : states) {
- if (connectionState == state) {
- devices.add(device);
- break;
- }
- }
- }
- return devices;
- }
- }
-
- List<BluetoothDevice> getConnectedDevices() {
- synchronized (mStateMachines) {
- List<BluetoothDevice> devices = new ArrayList<>();
- for (HapClientStateMachine sm : mStateMachines.values()) {
- if (sm.isConnected()) {
- devices.add(sm.getDevice());
- }
- }
- return devices;
- }
- }
-
- /**
- * Get the current connection state of the profile
- *
- * @param device is the remote bluetooth device
- * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected,
- * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected,
- * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or
- * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected
- */
- public int getConnectionState(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, "Need BLUETOOTH_CONNECT permission");
- synchronized (mStateMachines) {
- HapClientStateMachine sm = mStateMachines.get(device);
- if (sm == null) {
- return BluetoothProfile.STATE_DISCONNECTED;
- }
- return sm.getConnectionState();
- }
- }
-
- /**
- * Set connection policy of the profile and connects it if connectionPolicy is
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}
- *
- * <p> The device should already be paired.
- * Connection policy can be one of:
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
- * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
- *
- * @param device the remote device
- * @param connectionPolicy is the connection policy to set to for this profile
- * @return true on success, otherwise false
- */
- public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
- enforceBluetoothPrivilegedPermission(this);
- if (DBG) {
- Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy);
- }
- mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.HAP_CLIENT,
- connectionPolicy);
- if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
- connect(device);
- } else if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
- disconnect(device);
- }
- return true;
- }
-
- /**
- * Get the connection policy of the profile.
- *
- * <p> The connection policy can be any of:
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
- * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
- *
- * @param device Bluetooth device
- * @return connection policy of the device
- * @hide
- */
- public int getConnectionPolicy(BluetoothDevice device) {
- return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HAP_CLIENT);
- }
-
- /**
- * Check whether can connect to a peer device.
- * The check considers a number of factors during the evaluation.
- *
- * @param device the peer device to connect to
- * @return true if connection is allowed, otherwise false
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public boolean okToConnect(BluetoothDevice device) {
- // Check if this is an incoming connection in Quiet mode.
- if (mAdapterService.isQuietModeEnabled()) {
- Log.e(TAG, "okToConnect: cannot connect to " + device + " : quiet mode enabled");
- return false;
- }
- // Check connection policy and accept or reject the connection.
- int connectionPolicy = getConnectionPolicy(device);
- int bondState = mAdapterService.getBondState(device);
- // Allow this connection only if the device is bonded. Any attempt to connect while
- // bonding would potentially lead to an unauthorized connection.
- if (bondState != BluetoothDevice.BOND_BONDED) {
- Log.w(TAG, "okToConnect: return false, bondState=" + bondState);
- return false;
- } else if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_UNKNOWN
- && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
- // Otherwise, reject the connection if connectionPolicy is not valid.
- Log.w(TAG, "okToConnect: return false, connectionPolicy=" + connectionPolicy);
- return false;
- }
- return true;
- }
-
- @VisibleForTesting
- synchronized void connectionStateChanged(BluetoothDevice device, int fromState,
- int toState) {
- if ((device == null) || (fromState == toState)) {
- Log.e(TAG, "connectionStateChanged: unexpected invocation. device=" + device
- + " fromState=" + fromState + " toState=" + toState);
- return;
- }
-
- // Check if the device is disconnected - if unbond, remove the state machine
- if (toState == BluetoothProfile.STATE_DISCONNECTED) {
- int bondState = mAdapterService.getBondState(device);
- if (bondState == BluetoothDevice.BOND_NONE) {
- if (DBG) {
- Log.d(TAG, device + " is unbond. Remove state machine");
- }
- removeStateMachine(device);
- }
- }
- }
-
- /**
- * Connects the hearing access service client to the passed in device
- *
- * @param device is the device with which we will connect the hearing access service client
- * @return true if hearing access service client successfully connected, false otherwise
- */
- public boolean connect(BluetoothDevice device) {
- enforceBluetoothPrivilegedPermission(this);
- if (DBG) {
- Log.d(TAG, "connect(): " + device);
- }
- if (device == null) {
- return false;
- }
-
- if (getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
- return false;
- }
- ParcelUuid[] featureUuids = mAdapterService.getRemoteUuids(device);
- if (!Utils.arrayContains(featureUuids, BluetoothUuid.HAS)) {
- Log.e(TAG, "Cannot connect to " + device
- + " : Remote does not have Hearing Access Service UUID");
- return false;
- }
- synchronized (mStateMachines) {
- HapClientStateMachine smConnect = getOrCreateStateMachine(device);
- if (smConnect == null) {
- Log.e(TAG, "Cannot connect to " + device + " : no state machine");
- }
- smConnect.sendMessage(HapClientStateMachine.CONNECT);
- }
-
- return true;
- }
-
- /**
- * Disconnects hearing access service client for the passed in device
- *
- * @param device is the device with which we want to disconnect the hearing access service
- * client
- * @return true if hearing access service client successfully disconnected, false otherwise
- */
- public boolean disconnect(BluetoothDevice device) {
- enforceBluetoothPrivilegedPermission(this);
- if (DBG) {
- Log.d(TAG, "disconnect(): " + device);
- }
- if (device == null) {
- return false;
- }
- synchronized (mStateMachines) {
- HapClientStateMachine sm = mStateMachines.get(device);
- if (sm != null) {
- sm.sendMessage(HapClientStateMachine.DISCONNECT);
- }
- }
-
- return true;
- }
-
- private HapClientStateMachine getOrCreateStateMachine(BluetoothDevice device) {
- if (device == null) {
- Log.e(TAG, "getOrCreateStateMachine failed: device cannot be null");
- return null;
- }
- synchronized (mStateMachines) {
- HapClientStateMachine sm = mStateMachines.get(device);
- if (sm != null) {
- return sm;
- }
- // Limit the maximum number of state machines to avoid DoS attack
- if (mStateMachines.size() >= MAX_HEARING_ACCESS_STATE_MACHINES) {
- Log.e(TAG, "Maximum number of HearingAccess state machines reached: "
- + MAX_HEARING_ACCESS_STATE_MACHINES);
- return null;
- }
- if (DBG) {
- Log.d(TAG, "Creating a new state machine for " + device);
- }
- sm = HapClientStateMachine.make(device, this,
- mHapClientNativeInterface, mStateMachinesThread.getLooper());
- mStateMachines.put(device, sm);
- return sm;
- }
- }
-
- /**
- * Gets the hearing access device group of the passed device
- *
- * @param device is the device with which we want to get the group identifier for
- * @return group ID if device is part of the coordinated group, 0 otherwise
- */
- public int getHapGroup(BluetoothDevice device) {
- CsipSetCoordinatorService csipClient = mFactory.getCsipSetCoordinatorService();
-
- if (csipClient != null) {
- Map<Integer, ParcelUuid> groups = csipClient.getGroupUuidMapByDevice(device);
- for (Map.Entry<Integer, ParcelUuid> entry : groups.entrySet()) {
- if (entry.getValue().equals(BluetoothUuid.CAP)) {
- return entry.getKey();
- }
- }
- }
- return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
- }
-
- /**
- * Gets the currently active preset index for a HA device
- *
- * @param device is the device for which we want to get the currently active preset
- * @return active preset index
- */
- public int getActivePresetIndex(BluetoothDevice device) {
- return mDeviceCurrentPresetMap.getOrDefault(device,
- BluetoothHapClient.PRESET_INDEX_UNAVAILABLE);
- }
-
- /**
- * Gets the currently active preset info for a HA device
- *
- * @param device is the device for which we want to get the currently active preset info
- * @return active preset info or null if not available
- */
- public @Nullable BluetoothHapPresetInfo getActivePresetInfo(BluetoothDevice device) {
- int index = getActivePresetIndex(device);
- if (index == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return null;
-
- List<BluetoothHapPresetInfo> current_presets = mPresetsMap.get(device);
- if (current_presets != null) {
- for (BluetoothHapPresetInfo preset : current_presets) {
- if (preset.getIndex() == index) {
- return preset;
- }
- }
- }
-
- return null;
- }
-
- /**
- * Selects the currently active preset for a HA device
- *
- * @param device is the device for which we want to set the active preset
- * @param presetIndex is an index of one of the available presets
- */
- public void selectPreset(BluetoothDevice device, int presetIndex) {
- if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) {
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onPresetSelectionFailed(device,
- BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX);
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- return;
- }
-
- mHapClientNativeInterface.selectActivePreset(device, presetIndex);
- }
-
- /**
- * Selects the currently active preset for a HA device group.
- *
- * @param groupId is the device group identifier for which want to set the active preset
- * @param presetIndex is an index of one of the available presets
- */
- public void selectPresetForGroup(int groupId, int presetIndex) {
- int status = BluetoothStatusCodes.SUCCESS;
-
- if (!isGroupIdValid(groupId)) {
- status = BluetoothStatusCodes.ERROR_CSIP_INVALID_GROUP_ID;
- } else if (!isPresetIndexValid(groupId, presetIndex)) {
- status = BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX;
- }
-
- if (status != BluetoothStatusCodes.SUCCESS) {
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i)
- .onPresetSelectionForGroupFailed(groupId, status);
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- return;
- }
-
- mHapClientNativeInterface.groupSelectActivePreset(groupId, presetIndex);
- }
-
- /**
- * Sets the next preset as a currently active preset for a HA device
- *
- * @param device is the device for which we want to set the active preset
- */
- public void switchToNextPreset(BluetoothDevice device) {
- mHapClientNativeInterface.nextActivePreset(device);
- }
-
- /**
- * Sets the next preset as a currently active preset for a HA device group
- *
- * @param groupId is the device group identifier for which want to set the active preset
- */
- public void switchToNextPresetForGroup(int groupId) {
- mHapClientNativeInterface.groupNextActivePreset(groupId);
- }
-
- /**
- * Sets the previous preset as a currently active preset for a HA device
- *
- * @param device is the device for which we want to set the active preset
- */
- public void switchToPreviousPreset(BluetoothDevice device) {
- mHapClientNativeInterface.previousActivePreset(device);
- }
-
- /**
- * Sets the previous preset as a currently active preset for a HA device group
- *
- * @param groupId is the device group identifier for which want to set the active preset
- */
- public void switchToPreviousPresetForGroup(int groupId) {
- mHapClientNativeInterface.groupPreviousActivePreset(groupId);
- }
-
- /**
- * Requests the preset name
- *
- * @param device is the device for which we want to get the preset name
- * @param presetIndex is an index of one of the available presets
- * @return a preset Info corresponding to the requested preset index or null if not available
- */
- public @Nullable BluetoothHapPresetInfo getPresetInfo(BluetoothDevice device, int presetIndex) {
- BluetoothHapPresetInfo defaultValue = null;
- if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return defaultValue;
-
- if (Utils.isPtsTestMode()) {
- /* We want native to be called for PTS testing even we have all
- * the data in the cache here
- */
- mHapClientNativeInterface.getPresetInfo(device, presetIndex);
- }
- List<BluetoothHapPresetInfo> current_presets = mPresetsMap.get(device);
- if (current_presets != null) {
- for (BluetoothHapPresetInfo preset : current_presets) {
- if (preset.getIndex() == presetIndex) {
- return preset;
- }
- }
- }
-
- return defaultValue;
- }
-
- /**
- * Requests all presets info
- *
- * @param device is the device for which we want to get all presets info
- * @return a list of all presets Info
- */
- public List<BluetoothHapPresetInfo> getAllPresetInfo(BluetoothDevice device) {
- if (mPresetsMap.containsKey(device)) {
- return mPresetsMap.get(device);
- }
- return Collections.emptyList();
- }
-
- /**
- * Requests features
- *
- * @param device is the device for which we want to get features
- * @return integer with feature bits set
- */
- public int getFeatures(BluetoothDevice device) {
- if (mDeviceFeaturesMap.containsKey(device)) {
- return mDeviceFeaturesMap.get(device);
- }
- return 0x00;
- }
-
- private int stackEventPresetInfoReasonToProfileStatus(int statusCode) {
- switch (statusCode) {
- case HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO:
- return BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST;
- case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE:
- return BluetoothStatusCodes.REASON_REMOTE_REQUEST;
- case HapClientStackEvent.PRESET_INFO_REASON_PRESET_DELETED:
- return BluetoothStatusCodes.REASON_REMOTE_REQUEST;
- case HapClientStackEvent.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED:
- return BluetoothStatusCodes.REASON_REMOTE_REQUEST;
- case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE:
- return BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST;
- default:
- return BluetoothStatusCodes.ERROR_UNKNOWN;
- }
- }
-
- private void notifyPresetInfoChanged(BluetoothDevice device, int infoReason) {
- List current_presets = mPresetsMap.get(device);
- if (current_presets == null) return;
-
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onPresetInfoChanged(device, current_presets,
- stackEventPresetInfoReasonToProfileStatus(infoReason));
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- }
-
- private void notifyPresetInfoForGroupChanged(int groupId, int infoReason) {
- List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
- for (BluetoothDevice dev : all_group_devices) {
- notifyPresetInfoChanged(dev, infoReason);
- }
- }
-
- private void notifyFeaturesAvailable(BluetoothDevice device, int features) {
- Log.d(TAG, "HAP device: " + device + ", features: " + String.format("0x%04X", features));
- }
-
- private void notifyActivePresetChanged(BluetoothDevice device, int presetIndex,
- int reasonCode) {
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onPresetSelected(device, presetIndex,
- reasonCode);
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- }
-
- private void notifyActivePresetChangedForGroup(int groupId, int presetIndex, int reasonCode) {
- List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
- for (BluetoothDevice dev : all_group_devices) {
- notifyActivePresetChanged(dev, presetIndex, reasonCode);
- }
- }
-
- private int stackEventStatusToProfileStatus(int statusCode) {
- switch (statusCode) {
- case HapClientStackEvent.STATUS_SET_NAME_NOT_ALLOWED:
- return BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED;
- case HapClientStackEvent.STATUS_OPERATION_NOT_SUPPORTED:
- return BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED;
- case HapClientStackEvent.STATUS_OPERATION_NOT_POSSIBLE:
- return BluetoothStatusCodes.ERROR_REMOTE_OPERATION_REJECTED;
- case HapClientStackEvent.STATUS_INVALID_PRESET_NAME_LENGTH:
- return BluetoothStatusCodes.ERROR_HAP_PRESET_NAME_TOO_LONG;
- case HapClientStackEvent.STATUS_INVALID_PRESET_INDEX:
- return BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX;
- case HapClientStackEvent.STATUS_GROUP_OPERATION_NOT_SUPPORTED:
- return BluetoothStatusCodes.ERROR_REMOTE_OPERATION_NOT_SUPPORTED;
- case HapClientStackEvent.STATUS_PROCEDURE_ALREADY_IN_PROGRESS:
- return BluetoothStatusCodes.ERROR_UNKNOWN;
- default:
- return BluetoothStatusCodes.ERROR_UNKNOWN;
- }
- }
-
- private void notifySelectActivePresetFailed(BluetoothDevice device, int statusCode) {
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onPresetSelectionFailed(device,
- stackEventStatusToProfileStatus(statusCode));
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- }
-
- private void notifySelectActivePresetForGroupFailed(int groupId, int statusCode) {
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onPresetSelectionForGroupFailed(groupId,
- stackEventStatusToProfileStatus(statusCode));
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- }
-
- private void notifySetPresetNameFailed(BluetoothDevice device, int statusCode) {
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onSetPresetNameFailed(device,
- stackEventStatusToProfileStatus(statusCode));
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- }
-
- private void notifySetPresetNameForGroupFailed(int groupId, int statusCode) {
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onSetPresetNameForGroupFailed(groupId,
- stackEventStatusToProfileStatus(statusCode));
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- }
-
- private boolean isPresetIndexValid(BluetoothDevice device, int presetIndex) {
- if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) return false;
-
- List<BluetoothHapPresetInfo> device_presets = mPresetsMap.get(device);
- if (device_presets != null) {
- for (BluetoothHapPresetInfo preset : device_presets) {
- if (preset.getIndex() == presetIndex) {
- return true;
- }
- }
- }
- return false;
- }
-
- private boolean isPresetIndexValid(int groupId, int presetIndex) {
- List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
- if (all_group_devices.isEmpty()) return false;
-
- for (BluetoothDevice device : all_group_devices) {
- if (!isPresetIndexValid(device, presetIndex)) return false;
- }
- return true;
- }
-
-
- private boolean isGroupIdValid(int groupId) {
- if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return false;
-
- CsipSetCoordinatorService csipClient = mFactory.getCsipSetCoordinatorService();
- if (csipClient != null) {
- List<Integer> groups = csipClient.getAllGroupIds(BluetoothUuid.CAP);
- return groups.contains(groupId);
- }
- return false;
- }
-
- /**
- * Sets the preset name
- *
- * @param device is the device for which we want to get the preset name
- * @param presetIndex is an index of one of the available presets
- * @param name is a new name for a preset
- */
- public void setPresetName(BluetoothDevice device, int presetIndex, String name) {
- if (!isPresetIndexValid(device, presetIndex)) {
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onSetPresetNameFailed(device,
- BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX);
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- return;
- }
- // WARNING: We should check cache if preset exists and is writable, but then we would still
- // need a way to trigger this action with an invalid index or on a non-writable
- // preset for tests purpose.
- mHapClientNativeInterface.setPresetName(device, presetIndex, name);
- }
-
- /**
- * Sets the preset name
- *
- * @param groupId is the device group identifier
- * @param presetIndex is an index of one of the available presets
- * @param name is a new name for a preset
- */
- public void setPresetNameForGroup(int groupId, int presetIndex, String name) {
- int status = BluetoothStatusCodes.SUCCESS;
-
- if (!isGroupIdValid(groupId)) {
- status = BluetoothStatusCodes.ERROR_CSIP_INVALID_GROUP_ID;
- } else if (!isPresetIndexValid(groupId, presetIndex)) {
- status = BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX;
- }
- if (status != BluetoothStatusCodes.SUCCESS) {
- if (mCallbacks != null) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onSetPresetNameForGroupFailed(groupId,
- status);
- } catch (RemoteException e) {
- continue;
- }
- }
- mCallbacks.finishBroadcast();
- }
- return;
- }
-
- mHapClientNativeInterface.groupSetPresetName(groupId, presetIndex, name);
- }
-
- @Override
- public void dump(StringBuilder sb) {
- super.dump(sb);
- for (HapClientStateMachine sm : mStateMachines.values()) {
- sm.dump(sb);
- }
- }
-
- private boolean isPresetCoordinationSupported(BluetoothDevice device) {
- Integer features = mDeviceFeaturesMap.getOrDefault(device, 0x00);
- return BigInteger.valueOf(features).testBit(
- HapClientStackEvent.FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS);
- }
-
- void updateDevicePresetsCache(BluetoothDevice device, int infoReason,
- List<BluetoothHapPresetInfo> presets) {
- switch (infoReason) {
- case HapClientStackEvent.PRESET_INFO_REASON_ALL_PRESET_INFO:
- mPresetsMap.put(device, presets);
- break;
- case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE:
- case HapClientStackEvent.PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED:
- case HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE: {
- List current_presets = mPresetsMap.get(device);
- if (current_presets != null) {
- ListIterator<BluetoothHapPresetInfo> iter = current_presets.listIterator();
- for (BluetoothHapPresetInfo new_preset : presets) {
- while (iter.hasNext()) {
- if (iter.next().getIndex() == new_preset.getIndex()) {
- iter.remove();
- }
- }
- }
- current_presets.addAll(presets);
- mPresetsMap.put(device, current_presets);
- } else {
- mPresetsMap.put(device, presets);
- }
- }
- break;
-
- case HapClientStackEvent.PRESET_INFO_REASON_PRESET_DELETED: {
- List current_presets = mPresetsMap.get(device);
- if (current_presets != null) {
- ListIterator<BluetoothHapPresetInfo> iter = current_presets.listIterator();
- for (BluetoothHapPresetInfo new_preset : presets) {
- while (iter.hasNext()) {
- if (iter.next().getIndex() == new_preset.getIndex()) {
- iter.remove();
- }
- }
- }
- mPresetsMap.put(device, current_presets);
- }
- }
- break;
-
- default:
- break;
- }
- }
-
- private List<BluetoothDevice> getGroupDevices(int groupId) {
- List<BluetoothDevice> devices = new ArrayList<>();
-
- CsipSetCoordinatorService csipClient = mFactory.getCsipSetCoordinatorService();
- if (csipClient != null) {
- if (groupId != BluetoothLeAudio.GROUP_ID_INVALID) {
- //Phanee TODO:
- //devices = csipClient.getGroupUuidMapByDevice(groupId);
- }
- }
- return devices;
- }
-
- /**
- * Handle messages from native (JNI) to Java
- *
- * @param stackEvent the event that need to be handled
- */
- public void messageFromNative(HapClientStackEvent stackEvent) {
- // Decide which event should be sent to the state machine
- if (stackEvent.type == HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) {
- resendToStateMachine(stackEvent);
- return;
- }
-
- Intent intent = null;
- BluetoothDevice device = stackEvent.device;
-
- switch (stackEvent.type) {
- case (HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE): {
- int features = stackEvent.valueInt1;
-
- if (device != null) {
- mDeviceFeaturesMap.put(device, features);
-
- intent = new Intent(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, features);
- }
- } break;
-
- case (HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES): {
- int features = stackEvent.valueInt1;
-
- if (device != null) {
- mDeviceFeaturesMap.put(device, features);
- notifyFeaturesAvailable(device, features);
- }
- } return;
-
- case (HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED): {
- int currentPresetIndex = stackEvent.valueInt1;
- int groupId = stackEvent.valueInt2;
-
- if (device != null) {
- mDeviceCurrentPresetMap.put(device, currentPresetIndex);
- // FIXME: Add app request queueing to support other reasons
- int reasonCode = BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST;
- notifyActivePresetChanged(device, currentPresetIndex, reasonCode);
-
- } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
- List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
- for (BluetoothDevice dev : all_group_devices) {
- mDeviceCurrentPresetMap.put(dev, currentPresetIndex);
- }
- // FIXME: Add app request queueing to support other reasons
- int reasonCode = BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST;
- notifyActivePresetChangedForGroup(groupId, currentPresetIndex, reasonCode);
- }
- } return;
-
- case (HapClientStackEvent.EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR): {
- int groupId = stackEvent.valueInt2;
- int statusCode = stackEvent.valueInt1;
-
- if (device != null) {
- notifySelectActivePresetFailed(device, statusCode);
- } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
- notifySelectActivePresetForGroupFailed(groupId, statusCode);
- }
- } break;
-
- case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO): {
- int presetIndex = stackEvent.valueInt1;
- int infoReason = stackEvent.valueInt2;
- int groupId = stackEvent.valueInt3;
- ArrayList presets = stackEvent.valueList;
-
- if (device != null) {
- updateDevicePresetsCache(device, infoReason, presets);
- notifyPresetInfoChanged(device, infoReason);
-
- } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
- List<BluetoothDevice> all_group_devices = getGroupDevices(groupId);
- for (BluetoothDevice dev : all_group_devices) {
- updateDevicePresetsCache(dev, infoReason, presets);
- }
- notifyPresetInfoForGroupChanged(groupId, infoReason);
- }
-
- } return;
-
- case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_NAME_SET_ERROR): {
- int statusCode = stackEvent.valueInt1;
- int presetIndex = stackEvent.valueInt2;
- int groupId = stackEvent.valueInt3;
-
- if (device != null) {
- notifySetPresetNameFailed(device, statusCode);
- } else if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
- notifySetPresetNameForGroupFailed(groupId, statusCode);
- }
- } break;
-
- case (HapClientStackEvent.EVENT_TYPE_ON_PRESET_INFO_ERROR): {
- // Used only to report back on hidden API calls used for testing.
- Log.d(TAG, stackEvent.toString());
- } break;
-
- default:
- return;
- }
-
- if (intent != null) {
- sendBroadcast(intent, BLUETOOTH_PRIVILEGED);
- }
- }
-
- private void resendToStateMachine(HapClientStackEvent stackEvent) {
- synchronized (mStateMachines) {
- BluetoothDevice device = stackEvent.device;
- HapClientStateMachine sm = mStateMachines.get(device);
-
- if (sm == null) {
- if (stackEvent.type == HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) {
- switch (stackEvent.valueInt1) {
- case HapClientStackEvent.CONNECTION_STATE_CONNECTED:
- case HapClientStackEvent.CONNECTION_STATE_CONNECTING:
- sm = getOrCreateStateMachine(device);
- break;
- default:
- break;
- }
- }
- }
- if (sm == null) {
- Log.e(TAG, "Cannot process stack event: no state machine: " + stackEvent);
- return;
- }
- sm.sendMessage(HapClientStateMachine.STACK_EVENT, stackEvent);
- }
- }
-
- /**
- * Binder object: must be a static class or memory leak may occur
- */
- @VisibleForTesting
- static class BluetoothHapClientBinder extends IBluetoothHapClient.Stub
- implements IProfileServiceBinder {
- @VisibleForTesting
- boolean mIsTesting = false;
- private HapClientService mService;
-
- BluetoothHapClientBinder(HapClientService svc) {
- mService = svc;
- }
-
- private HapClientService getService(AttributionSource source) {
- if (mIsTesting) {
- return mService;
- }
- if (!Utils.checkServiceAvailable(mService, TAG)
- || !Utils.checkCallerIsSystemOrActiveOrManagedUser(mService, TAG)
- || !Utils.checkConnectPermissionForDataDelivery(mService, source, TAG)) {
- Log.w(TAG, "Hearing Access call not allowed for non-active user");
- return null;
- }
-
- if (mService != null && mService.isAvailable()) {
- return mService;
- }
- return null;
- }
-
- @Override
- public void cleanup() {
- mService = null;
- }
-
- @Override
- public void getConnectedDevices(AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- List<BluetoothDevice> defaultValue = new ArrayList<>();
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getConnectedDevices();
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void getDevicesMatchingConnectionStates(int[] states,
- AttributionSource source, SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- List<BluetoothDevice> defaultValue = new ArrayList<>();
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getDevicesMatchingConnectionStates(states);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void getConnectionState(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(device, "device cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getConnectionState(device);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void setConnectionPolicy(BluetoothDevice device, int connectionPolicy,
- AttributionSource source, SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(device, "device cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- boolean defaultValue = false;
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.setConnectionPolicy(device, connectionPolicy);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void getConnectionPolicy(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(device, "device cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- int defaultValue = BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getConnectionPolicy(device);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void getActivePresetIndex(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(device, "device cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- int defaultValue = BluetoothHapClient.PRESET_INDEX_UNAVAILABLE;
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getActivePresetIndex(device);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void getActivePresetInfo(BluetoothDevice device,
- AttributionSource source, SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(device, "device cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- BluetoothHapPresetInfo defaultValue = null;
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getActivePresetInfo(device);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void getHapGroup(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(device, "device cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- int defaultValue = BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getHapGroup(device);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void selectPreset(BluetoothDevice device, int presetIndex,
- AttributionSource source) {
- if (source == null) {
- Log.w(TAG, "source cannot be null");
- return;
- }
-
- HapClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "service is null");
- return;
- }
- enforceBluetoothPrivilegedPermission(service);
- service.selectPreset(device, presetIndex);
- }
-
- @Override
- public void selectPresetForGroup(int groupId, int presetIndex, AttributionSource source) {
- if (source == null) {
- Log.w(TAG, "source cannot be null");
- return;
- }
-
- HapClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "service is null");
- return;
- }
- enforceBluetoothPrivilegedPermission(service);
- service.selectPresetForGroup(groupId, presetIndex);
- }
-
- @Override
- public void switchToNextPreset(BluetoothDevice device, AttributionSource source) {
- if (source == null) {
- Log.w(TAG, "source cannot be null");
- return;
- }
-
- HapClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "service is null");
- return;
- }
- enforceBluetoothPrivilegedPermission(service);
- service.switchToNextPreset(device);
- }
-
- @Override
- public void switchToNextPresetForGroup(int groupId, AttributionSource source) {
- if (source == null) {
- Log.w(TAG, "source cannot be null");
- return;
- }
-
- HapClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "service is null");
- return;
- }
- enforceBluetoothPrivilegedPermission(service);
- service.switchToNextPresetForGroup(groupId);
- }
-
- @Override
- public void switchToPreviousPreset(BluetoothDevice device, AttributionSource source) {
- if (source == null) {
- Log.w(TAG, "source cannot be null");
- return;
- }
-
- HapClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "service is null");
- return;
- }
- enforceBluetoothPrivilegedPermission(service);
- service.switchToPreviousPreset(device);
- }
-
- @Override
- public void switchToPreviousPresetForGroup(int groupId, AttributionSource source) {
- if (source == null) {
- Log.w(TAG, "source cannot be null");
- return;
- }
-
- HapClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "service is null");
- return;
- }
- enforceBluetoothPrivilegedPermission(service);
- service.switchToPreviousPresetForGroup(groupId);
- }
-
- @Override
- public void getPresetInfo(BluetoothDevice device, int presetIndex,
- AttributionSource source, SynchronousResultReceiver receiver) {
-
- try {
- Objects.requireNonNull(device, "device cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- BluetoothHapPresetInfo defaultValue = null;
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getPresetInfo(device, presetIndex);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void getAllPresetInfo(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(device, "device cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- List<BluetoothHapPresetInfo> defaultValue = new ArrayList<>();
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getAllPresetInfo(device);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void getFeatures(BluetoothDevice device, AttributionSource source,
- SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(device, "device cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- int defaultValue = 0x00;
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("service is null");
- }
- enforceBluetoothPrivilegedPermission(service);
- defaultValue = service.getFeatures(device);
- receiver.send(defaultValue);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void setPresetName(BluetoothDevice device, int presetIndex, String name,
- AttributionSource source) {
- if (device == null) {
- Log.w(TAG, "device cannot be null");
- return;
- }
- if (name == null) {
- Log.w(TAG, "name cannot be null");
- return;
- }
- if (source == null) {
- Log.w(TAG, "source cannot be null");
- return;
- }
-
- HapClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "service is null");
- return;
- }
- enforceBluetoothPrivilegedPermission(service);
- service.setPresetName(device, presetIndex, name);
- }
-
- @Override
- public void setPresetNameForGroup(int groupId, int presetIndex, String name,
- AttributionSource source) {
- if (name == null) {
- Log.w(TAG, "name cannot be null");
- return;
- }
- if (source == null) {
- Log.w(TAG, "source cannot be null");
- return;
- }
- HapClientService service = getService(source);
- if (service == null) {
- Log.w(TAG, "service is null");
- return;
- }
- enforceBluetoothPrivilegedPermission(service);
- service.setPresetNameForGroup(groupId, presetIndex, name);
- }
-
- @Override
- public void registerCallback(IBluetoothHapClientCallback callback,
- AttributionSource source, SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(callback, "callback cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("Service is unavailable");
- }
- enforceBluetoothPrivilegedPermission(service);
- service.mCallbacks.register(callback);
- receiver.send(null);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
-
- @Override
- public void unregisterCallback(IBluetoothHapClientCallback callback,
- AttributionSource source, SynchronousResultReceiver receiver) {
- try {
- Objects.requireNonNull(callback, "callback cannot be null");
- Objects.requireNonNull(source, "source cannot be null");
- Objects.requireNonNull(receiver, "receiver cannot be null");
-
- HapClientService service = getService(source);
- if (service == null) {
- throw new IllegalStateException("Service is unavailable");
- }
- enforceBluetoothPrivilegedPermission(service);
- service.mCallbacks.unregister(callback);
- receiver.send(null);
- } catch (RuntimeException e) {
- receiver.propagateException(e);
- }
- }
- }
-
- // Remove state machine if the bonding for a device is removed
- private class BondStateChangedReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
- return;
- }
- int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
- BluetoothDevice.ERROR);
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- Objects.requireNonNull(device, "ACTION_BOND_STATE_CHANGED with no EXTRA_DEVICE");
- bondStateChanged(device, state);
- }
- }
-
- private class ConnectionStateChangedReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED.equals(
- intent.getAction())) {
- return;
- }
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- int toState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
- int fromState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
- connectionStateChanged(device, fromState, toState);
- }
- }
-}
diff --git a/src/com/android/bluetooth/hap/HapClientStackEvent.java b/src/com/android/bluetooth/hap/HapClientStackEvent.java
deleted file mode 100644
index 5911c293e..000000000
--- a/src/com/android/bluetooth/hap/HapClientStackEvent.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.bluetooth.hap;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.IBluetoothHapClient;
-
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Stack event sent via a callback from GATT Service client to main service module, or generated
- * internally by the Hearing Access Profile State Machine.
- */
-public class HapClientStackEvent {
- // Event types for STACK_EVENT message (coming from native HAS client)
- private static final int EVENT_TYPE_NONE = 0;
- public static final int EVENT_TYPE_CONNECTION_STATE_CHANGED = 1;
- public static final int EVENT_TYPE_DEVICE_AVAILABLE = 2;
- public static final int EVENT_TYPE_DEVICE_FEATURES = 3;
- public static final int EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED = 4;
- public static final int EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR = 5;
- public static final int EVENT_TYPE_ON_PRESET_INFO = 6;
- public static final int EVENT_TYPE_ON_PRESET_NAME_SET_ERROR = 7;
- public static final int EVENT_TYPE_ON_PRESET_INFO_ERROR = 8;
-
- // Connection state values as defined in bt_has.h
- static final int CONNECTION_STATE_DISCONNECTED = 0;
- static final int CONNECTION_STATE_CONNECTING = 1;
- static final int CONNECTION_STATE_CONNECTED = 2;
- static final int CONNECTION_STATE_DISCONNECTING = 3;
-
- // Possible operation results
- /* WARNING: Matches status codes defined in bta_has.h */
- static final int STATUS_NO_ERROR = 0;
- static final int STATUS_SET_NAME_NOT_ALLOWED = 1;
- static final int STATUS_OPERATION_NOT_SUPPORTED = 2;
- static final int STATUS_OPERATION_NOT_POSSIBLE = 3;
- static final int STATUS_INVALID_PRESET_NAME_LENGTH = 4;
- static final int STATUS_INVALID_PRESET_INDEX = 5;
- static final int STATUS_GROUP_OPERATION_NOT_SUPPORTED = 6;
- static final int STATUS_PROCEDURE_ALREADY_IN_PROGRESS = 7;
-
- // Supported features
- public static final int FEATURE_BIT_NUM_TYPE_MONAURAL =
- IBluetoothHapClient.FEATURE_BIT_NUM_TYPE_MONAURAL;
- public static final int FEATURE_BIT_NUM_TYPE_BANDED =
- IBluetoothHapClient.FEATURE_BIT_NUM_TYPE_BANDED;
- public static final int FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS =
- IBluetoothHapClient.FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS;
- public static final int FEATURE_BIT_NUM_INDEPENDENT_PRESETS =
- IBluetoothHapClient.FEATURE_BIT_NUM_INDEPENDENT_PRESETS;
- public static final int FEATURE_BIT_NUM_DYNAMIC_PRESETS =
- IBluetoothHapClient.FEATURE_BIT_NUM_DYNAMIC_PRESETS;
- public static final int FEATURE_BIT_NUM_WRITABLE_PRESETS =
- IBluetoothHapClient.FEATURE_BIT_NUM_WRITABLE_PRESETS;
-
- // Preset Info notification reason
- /* WARNING: Matches status codes defined in bta_has.h */
- public static final int PRESET_INFO_REASON_ALL_PRESET_INFO = 0;
- public static final int PRESET_INFO_REASON_PRESET_INFO_UPDATE = 1;
- public static final int PRESET_INFO_REASON_PRESET_DELETED = 2;
- public static final int PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED = 3;
- public static final int PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE = 4;
-
- public int type;
- public BluetoothDevice device;
- public int valueInt1;
- public int valueInt2;
- public int valueInt3;
- public ArrayList valueList;
-
- public HapClientStackEvent(int type) {
- this.type = type;
- }
-
- @Override
- public String toString() {
- // event dump
- StringBuilder result = new StringBuilder();
- result.append("HearingAccessStackEvent {type:" + eventTypeToString(type));
- result.append(", device: " + device);
- result.append(", value1: " + eventTypeValueInt1ToString(type, valueInt1));
- result.append(", value2: " + eventTypeValueInt2ToString(type, valueInt2));
- result.append(", value3: " + eventTypeValueInt3ToString(type, valueInt3));
- result.append(", list: " + eventTypeValueListToString(type, valueList));
-
- result.append("}");
- return result.toString();
- }
-
- private String eventTypeValueListToString(int type, List value) {
- switch (type) {
- case EVENT_TYPE_ON_PRESET_INFO:
- return "{presets count: " + (value == null ? 0 : value.size()) + "}";
- default:
- return "{list: empty}";
- }
- }
-
- private String eventTypeValueInt1ToString(int type, int value) {
- switch (type) {
- case EVENT_TYPE_CONNECTION_STATE_CHANGED:
- return "{state: " + connectionStateValueToString(value) + "}";
- case EVENT_TYPE_DEVICE_AVAILABLE:
- return "{features: " + featuresToString(value) + "}";
- case EVENT_TYPE_DEVICE_FEATURES:
- return "{features: " + featuresToString(value) + "}";
- case EVENT_TYPE_ON_PRESET_NAME_SET_ERROR:
- return "{statusCode: " + statusCodeValueToString(value) + "}";
- case EVENT_TYPE_ON_PRESET_INFO_ERROR:
- return "{statusCode: " + statusCodeValueToString(value) + "}";
- case EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED:
- return "{presetIndex: " + value + "}";
- case EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR:
- return "{statusCode: " + statusCodeValueToString(value) + "}";
- case EVENT_TYPE_ON_PRESET_INFO:
- default:
- return "{unused: " + value + "}";
- }
- }
-
- private String infoReasonToString(int value) {
- switch (value) {
- case PRESET_INFO_REASON_ALL_PRESET_INFO:
- return "PRESET_INFO_REASON_ALL_PRESET_INFO";
- case PRESET_INFO_REASON_PRESET_INFO_UPDATE:
- return "PRESET_INFO_REASON_PRESET_INFO_UPDATE";
- case PRESET_INFO_REASON_PRESET_DELETED:
- return "PRESET_INFO_REASON_PRESET_DELETED";
- case PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED:
- return "PRESET_INFO_REASON_PRESET_AVAILABILITY_CHANGED";
- case PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE:
- return "PRESET_INFO_REASON_PRESET_INFO_REQUEST_RESPONSE";
- default:
- return "UNKNOWN";
- }
- }
-
- private String eventTypeValueInt2ToString(int type, int value) {
- switch (type) {
- case EVENT_TYPE_ON_PRESET_NAME_SET_ERROR:
- return "{presetIndex: " + value + "}";
- case EVENT_TYPE_ON_PRESET_INFO:
- return "{info_reason: " + infoReasonToString(value) + "}";
- case EVENT_TYPE_ON_PRESET_INFO_ERROR:
- return "{presetIndex: " + value + "}";
- case EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED:
- return "{groupId: " + value + "}";
- case EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR:
- return "{groupId: " + value + "}";
- default:
- return "{unused: " + value + "}";
- }
- }
-
- private String eventTypeValueInt3ToString(int type, int value) {
- switch (type) {
- case EVENT_TYPE_ON_PRESET_INFO:
- case EVENT_TYPE_ON_PRESET_INFO_ERROR:
- case EVENT_TYPE_ON_PRESET_NAME_SET_ERROR:
- return "{groupId: " + value + "}";
- default:
- return "{unused: " + value + "}";
- }
- }
-
- private String connectionStateValueToString(int value) {
- switch (value) {
- case CONNECTION_STATE_DISCONNECTED:
- return "CONNECTION_STATE_DISCONNECTED";
- case CONNECTION_STATE_CONNECTING:
- return "CONNECTION_STATE_CONNECTING";
- case CONNECTION_STATE_CONNECTED:
- return "CONNECTION_STATE_CONNECTED";
- case CONNECTION_STATE_DISCONNECTING:
- return "CONNECTION_STATE_DISCONNECTING";
- default:
- return "CONNECTION_STATE_UNKNOWN!";
- }
- }
-
- private String statusCodeValueToString(int value) {
- switch (value) {
- case STATUS_NO_ERROR:
- return "STATUS_NO_ERROR";
- case STATUS_SET_NAME_NOT_ALLOWED:
- return "STATUS_SET_NAME_NOT_ALLOWED";
- case STATUS_OPERATION_NOT_SUPPORTED:
- return "STATUS_OPERATION_NOT_SUPPORTED";
- case STATUS_OPERATION_NOT_POSSIBLE:
- return "STATUS_OPERATION_NOT_POSSIBLE";
- case STATUS_INVALID_PRESET_NAME_LENGTH:
- return "STATUS_INVALID_PRESET_NAME_LENGTH";
- case STATUS_INVALID_PRESET_INDEX:
- return "STATUS_INVALID_PRESET_INDEX";
- case STATUS_GROUP_OPERATION_NOT_SUPPORTED:
- return "STATUS_GROUP_OPERATION_NOT_SUPPORTED";
- case STATUS_PROCEDURE_ALREADY_IN_PROGRESS:
- return "STATUS_PROCEDURE_ALREADY_IN_PROGRESS";
- default:
- return "ERROR_UNKNOWN";
- }
- }
-
- private String featuresToString(int value) {
- String features_str = "";
- if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_TYPE_MONAURAL)) {
- features_str += "TYPE_MONAURAL";
- } else if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_TYPE_BANDED)) {
- features_str += "TYPE_BANDED";
- } else {
- features_str += "TYPE_BINAURAL";
- }
-
- if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_SYNCHRONIZATED_PRESETS)) {
- features_str += ", SYNCHRONIZATED_PRESETS";
- }
- if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_INDEPENDENT_PRESETS)) {
- features_str += ", INDEPENDENT_PRESETS";
- }
- if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_DYNAMIC_PRESETS)) {
- features_str += ", DYNAMIC_PRESETS";
- }
- if (BigInteger.valueOf(value).testBit(FEATURE_BIT_NUM_WRITABLE_PRESETS)) {
- features_str += ", WRITABLE_PRESETS";
- }
-
- return features_str;
- }
-
- private static String eventTypeToString(int type) {
- switch (type) {
- case EVENT_TYPE_NONE:
- return "EVENT_TYPE_NONE";
- case EVENT_TYPE_CONNECTION_STATE_CHANGED:
- return "EVENT_TYPE_CONNECTION_STATE_CHANGED";
- case EVENT_TYPE_DEVICE_AVAILABLE:
- return "EVENT_TYPE_DEVICE_AVAILABLE";
- case EVENT_TYPE_DEVICE_FEATURES:
- return "EVENT_TYPE_DEVICE_FEATURES";
- case EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED:
- return "EVENT_TYPE_ON_ACTIVE_PRESET_SELECTED";
- case EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR:
- return "EVENT_TYPE_ON_ACTIVE_PRESET_SELECT_ERROR";
- case EVENT_TYPE_ON_PRESET_INFO:
- return "EVENT_TYPE_ON_PRESET_INFO";
- case EVENT_TYPE_ON_PRESET_NAME_SET_ERROR:
- return "EVENT_TYPE_ON_PRESET_NAME_SET_ERROR";
- case EVENT_TYPE_ON_PRESET_INFO_ERROR:
- return "EVENT_TYPE_ON_PRESET_INFO_ERROR";
- default:
- return "EVENT_TYPE_UNKNOWN:" + type;
- }
- }
-}
diff --git a/src/com/android/bluetooth/hap/HapClientStateMachine.java b/src/com/android/bluetooth/hap/HapClientStateMachine.java
deleted file mode 100644
index dc85f0aea..000000000
--- a/src/com/android/bluetooth/hap/HapClientStateMachine.java
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com.
- * Represented by EHIMA - www.ehima.com
- *
- * 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.
- */
-
-/**
- * Bluetooth Hap Client StateMachine. There is one instance per remote device.
- * - "Disconnected" and "Connected" are steady states.
- * - "Connecting" and "Disconnecting" are transient states until the
- * connection / disconnection is completed.
- *
- *
- * (Disconnected)
- * | ^
- * CONNECT | | DISCONNECTED
- * V |
- * (Connecting)<--->(Disconnecting)
- * | ^
- * CONNECTED | | DISCONNECT
- * V |
- * (Connected)
- * NOTES:
- * - If state machine is in "Connecting" state and the remote device sends
- * DISCONNECT request, the state machine transitions to "Disconnecting" state.
- * - Similarly, if the state machine is in "Disconnecting" state and the remote device
- * sends CONNECT request, the state machine transitions to "Connecting" state.
- *
- * DISCONNECT
- * (Connecting) ---------------> (Disconnecting)
- * <---------------
- * CONNECT
- *
- */
-
-package com.android.bluetooth.hap;
-
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHapClient;
-import android.bluetooth.BluetoothProfile;
-import android.content.Intent;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.bluetooth.btservice.ProfileService;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Scanner;
-
-final class HapClientStateMachine extends StateMachine {
- static final int CONNECT = 1;
- static final int DISCONNECT = 2;
- @VisibleForTesting
- static final int STACK_EVENT = 101;
- private static final boolean DBG = true;
- private static final String TAG = "HapClientStateMachine";
- @VisibleForTesting
- static final int CONNECT_TIMEOUT = 201;
-
- // NOTE: the value is not "final" - it is modified in the unit tests
- @VisibleForTesting
- static int sConnectTimeoutMs = 30000; // 30s
-
- private final Disconnected mDisconnected;
- private final Connecting mConnecting;
- private final Disconnecting mDisconnecting;
- private final Connected mConnected;
- private int mConnectionState = BluetoothProfile.STATE_DISCONNECTED;
- private int mLastConnectionState = -1;
-
- private final HapClientService mService;
- private final HapClientNativeInterface mNativeInterface;
-
- private final BluetoothDevice mDevice;
-
- HapClientStateMachine(BluetoothDevice device, HapClientService svc,
- HapClientNativeInterface gattInterface, Looper looper) {
- super(TAG, looper);
- mDevice = device;
- mService = svc;
- mNativeInterface = gattInterface;
-
- mDisconnected = new Disconnected();
- mConnecting = new Connecting();
- mDisconnecting = new Disconnecting();
- mConnected = new Connected();
-
- addState(mDisconnected);
- addState(mConnecting);
- addState(mDisconnecting);
- addState(mConnected);
-
- setInitialState(mDisconnected);
- }
-
- static HapClientStateMachine make(BluetoothDevice device, HapClientService svc,
- HapClientNativeInterface gattInterface, Looper looper) {
- Log.i(TAG, "make for device " + device);
- HapClientStateMachine hearingAccessSm = new HapClientStateMachine(device, svc,
- gattInterface, looper);
- hearingAccessSm.start();
- return hearingAccessSm;
- }
-
- private static String messageWhatToString(int what) {
- switch (what) {
- case CONNECT:
- return "CONNECT";
- case DISCONNECT:
- return "DISCONNECT";
- case STACK_EVENT:
- return "STACK_EVENT";
- case CONNECT_TIMEOUT:
- return "CONNECT_TIMEOUT";
- default:
- break;
- }
- return Integer.toString(what);
- }
-
- private static String profileStateToString(int state) {
- switch (state) {
- case BluetoothProfile.STATE_DISCONNECTED:
- return "DISCONNECTED";
- case BluetoothProfile.STATE_CONNECTING:
- return "CONNECTING";
- case BluetoothProfile.STATE_CONNECTED:
- return "CONNECTED";
- case BluetoothProfile.STATE_DISCONNECTING:
- return "DISCONNECTING";
- default:
- break;
- }
- return Integer.toString(state);
- }
-
- public void doQuit() {
- log("doQuit for device " + mDevice);
- quitNow();
- }
-
- public void cleanup() {
- log("cleanup for device " + mDevice);
- }
-
- int getConnectionState() {
- return mConnectionState;
- }
-
- BluetoothDevice getDevice() {
- return mDevice;
- }
-
- synchronized boolean isConnected() {
- return (getConnectionState() == BluetoothProfile.STATE_CONNECTED);
- }
-
- // This method does not check for error condition (newState == prevState)
- private void broadcastConnectionState(int newState, int prevState) {
- log("Connection state " + mDevice + ": " + profileStateToString(prevState)
- + "->" + profileStateToString(newState));
-
- Intent intent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
- intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
- intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- mService.sendBroadcast(intent, BLUETOOTH_CONNECT);
- }
-
- public void dump(StringBuilder sb) {
- ProfileService.println(sb, "mDevice: " + mDevice);
- ProfileService.println(sb, " StateMachine: " + this);
- // Dump the state machine logs
- StringWriter stringWriter = new StringWriter();
- PrintWriter printWriter = new PrintWriter(stringWriter);
- super.dump(new FileDescriptor(), printWriter, new String[]{});
- printWriter.flush();
- stringWriter.flush();
- ProfileService.println(sb, " StateMachineLog:");
- Scanner scanner = new Scanner(stringWriter.toString());
- while (scanner.hasNextLine()) {
- String line = scanner.nextLine();
- ProfileService.println(sb, " " + line);
- }
- scanner.close();
- }
-
- @Override
- protected void log(String msg) {
- if (DBG) {
- super.log(msg);
- }
- }
-
- @VisibleForTesting
- class Disconnected extends State {
- @Override
- public void enter() {
- Log.i(TAG, "Enter Disconnected(" + mDevice + "): " + messageWhatToString(
- getCurrentMessage().what));
- mConnectionState = BluetoothProfile.STATE_DISCONNECTED;
-
- removeDeferredMessages(DISCONNECT);
-
- if (mLastConnectionState != -1) {
- // Don't broadcast during startup
- broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED,
- mLastConnectionState);
- }
- }
-
- @Override
- public void exit() {
- log("Exit Disconnected(" + mDevice + "): " + messageWhatToString(
- getCurrentMessage().what));
- mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED;
- }
-
- @Override
- public boolean processMessage(Message message) {
- log("Disconnected: process message(" + mDevice + "): " + messageWhatToString(
- message.what));
-
- switch (message.what) {
- case CONNECT:
- log("Connecting to " + mDevice);
- if (!mNativeInterface.connectHapClient(mDevice)) {
- Log.e(TAG, "Disconnected: error connecting to " + mDevice);
- break;
- }
- if (mService.okToConnect(mDevice)) {
- transitionTo(mConnecting);
- } else {
- // Reject the request and stay in Disconnected state
- Log.w(TAG, "Outgoing HearingAccess Connecting request rejected: "
- + mDevice);
- }
- break;
- case DISCONNECT:
- Log.d(TAG, "Disconnected: DISCONNECT: call native disconnect for " + mDevice);
- mNativeInterface.disconnectHapClient(mDevice);
- break;
- case STACK_EVENT:
- HapClientStackEvent event = (HapClientStackEvent) message.obj;
- if (DBG) {
- Log.d(TAG, "Disconnected: stack event: " + event);
- }
- if (!mDevice.equals(event.device)) {
- Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event);
- }
- switch (event.type) {
- case HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
- processConnectionEvent(event.valueInt1);
- break;
- default:
- Log.e(TAG, "Disconnected: ignoring stack event: " + event);
- break;
- }
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- // in Disconnected state
- private void processConnectionEvent(int state) {
- switch (state) {
- case HapClientStackEvent.CONNECTION_STATE_DISCONNECTED:
- Log.w(TAG, "Ignore HearingAccess DISCONNECTED event: " + mDevice);
- break;
- case HapClientStackEvent.CONNECTION_STATE_CONNECTING:
- if (mService.okToConnect(mDevice)) {
- Log.i(TAG, "Incoming HearingAccess Connecting request accepted: "
- + mDevice);
- transitionTo(mConnecting);
- } else {
- // Reject the connection and stay in Disconnected state itself
- Log.w(TAG, "Incoming HearingAccess Connecting request rejected: "
- + mDevice);
- mNativeInterface.disconnectHapClient(mDevice);
- }
- break;
- case HapClientStackEvent.CONNECTION_STATE_CONNECTED:
- Log.w(TAG, "HearingAccess Connected from Disconnected state: " + mDevice);
- if (mService.okToConnect(mDevice)) {
- Log.i(TAG, "Incoming HearingAccess Connected request accepted: " + mDevice);
- transitionTo(mConnected);
- } else {
- // Reject the connection and stay in Disconnected state itself
- Log.w(TAG, "Incoming HearingAccess Connected request rejected: " + mDevice);
- mNativeInterface.disconnectHapClient(mDevice);
- }
- break;
- case HapClientStackEvent.CONNECTION_STATE_DISCONNECTING:
- Log.w(TAG, "Ignore HearingAccess DISCONNECTING event: " + mDevice);
- break;
- default:
- Log.e(TAG, "Incorrect state: " + state + " device: " + mDevice);
- break;
- }
- }
- }
-
- @VisibleForTesting
- class Connecting extends State {
- @Override
- public void enter() {
- Log.i(TAG, "Enter Connecting(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
- sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
- mConnectionState = BluetoothProfile.STATE_CONNECTING;
- broadcastConnectionState(BluetoothProfile.STATE_CONNECTING, mLastConnectionState);
- }
-
- @Override
- public void exit() {
- log("Exit Connecting(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
- mLastConnectionState = BluetoothProfile.STATE_CONNECTING;
- removeMessages(CONNECT_TIMEOUT);
- }
-
- @Override
- public boolean processMessage(Message message) {
- log("Connecting: process message(" + mDevice + "): "
- + messageWhatToString(message.what));
-
- switch (message.what) {
- case CONNECT:
- deferMessage(message);
- break;
- case CONNECT_TIMEOUT:
- Log.w(TAG, "Connecting connection timeout: " + mDevice);
- mNativeInterface.disconnectHapClient(mDevice);
- HapClientStackEvent disconnectEvent =
- new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- disconnectEvent.device = mDevice;
- disconnectEvent.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTED;
- sendMessage(STACK_EVENT, disconnectEvent);
- break;
- case DISCONNECT:
- log("Connecting: connection canceled to " + mDevice);
- mNativeInterface.disconnectHapClient(mDevice);
- transitionTo(mDisconnected);
- break;
- case STACK_EVENT:
- HapClientStackEvent event = (HapClientStackEvent) message.obj;
- log("Connecting: stack event: " + event);
- if (!mDevice.equals(event.device)) {
- Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event);
- }
- switch (event.type) {
- case HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
- processConnectionEvent(event.valueInt1);
- break;
- default:
- Log.e(TAG, "Connecting: ignoring stack event: " + event);
- break;
- }
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- // in Connecting state
- private void processConnectionEvent(int state) {
- switch (state) {
- case HapClientStackEvent.CONNECTION_STATE_DISCONNECTED:
- Log.w(TAG, "Connecting device disconnected: " + mDevice);
- transitionTo(mDisconnected);
- break;
- case HapClientStackEvent.CONNECTION_STATE_CONNECTED:
- transitionTo(mConnected);
- break;
- case HapClientStackEvent.CONNECTION_STATE_CONNECTING:
- break;
- case HapClientStackEvent.CONNECTION_STATE_DISCONNECTING:
- Log.w(TAG, "Connecting interrupted: device is disconnecting: " + mDevice);
- transitionTo(mDisconnecting);
- break;
- default:
- Log.e(TAG, "Incorrect state: " + state);
- break;
- }
- }
- }
-
- @VisibleForTesting
- class Disconnecting extends State {
- @Override
- public void enter() {
- Log.i(TAG, "Enter Disconnecting(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
- sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
- mConnectionState = BluetoothProfile.STATE_DISCONNECTING;
- broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTING, mLastConnectionState);
- }
-
- @Override
- public void exit() {
- log("Exit Disconnecting(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
- mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING;
- removeMessages(CONNECT_TIMEOUT);
- }
-
- @Override
- public boolean processMessage(Message message) {
- log("Disconnecting: process message(" + mDevice + "): "
- + messageWhatToString(message.what));
-
- switch (message.what) {
- case CONNECT:
- deferMessage(message);
- break;
- case CONNECT_TIMEOUT: {
- Log.w(TAG, "Disconnecting connection timeout: " + mDevice);
- mNativeInterface.disconnectHapClient(mDevice);
-
- HapClientStackEvent disconnectEvent =
- new HapClientStackEvent(
- HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- disconnectEvent.device = mDevice;
- disconnectEvent.valueInt1 = HapClientStackEvent.CONNECTION_STATE_DISCONNECTED;
- sendMessage(STACK_EVENT, disconnectEvent);
- break;
- }
- case DISCONNECT:
- deferMessage(message);
- break;
- case STACK_EVENT:
- HapClientStackEvent event = (HapClientStackEvent) message.obj;
- log("Disconnecting: stack event: " + event);
- if (!mDevice.equals(event.device)) {
- Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event);
- }
- switch (event.type) {
- case HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
- processConnectionEvent(event.valueInt1);
- break;
- default:
- Log.e(TAG, "Disconnecting: ignoring stack event: " + event);
- break;
- }
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- // in Disconnecting state
- private void processConnectionEvent(int state) {
- switch (state) {
- case HapClientStackEvent.CONNECTION_STATE_DISCONNECTED:
- Log.i(TAG, "Disconnected: " + mDevice);
- transitionTo(mDisconnected);
- break;
- case HapClientStackEvent.CONNECTION_STATE_CONNECTED:
- if (mService.okToConnect(mDevice)) {
- Log.w(TAG, "Disconnecting interrupted: device is connected: " + mDevice);
- transitionTo(mConnected);
- } else {
- // Reject the connection and stay in Disconnecting state
- Log.w(TAG, "Incoming HearingAccess Connected request rejected: " + mDevice);
- mNativeInterface.disconnectHapClient(mDevice);
- }
- break;
- case HapClientStackEvent.CONNECTION_STATE_CONNECTING:
- if (mService.okToConnect(mDevice)) {
- Log.i(TAG, "Disconnecting interrupted: try to reconnect: " + mDevice);
- transitionTo(mConnecting);
- } else {
- // Reject the connection and stay in Disconnecting state
- Log.w(TAG, "Incoming HearingAccess Connecting request rejected: "
- + mDevice);
- mNativeInterface.disconnectHapClient(mDevice);
- }
- break;
- case HapClientStackEvent.CONNECTION_STATE_DISCONNECTING:
- break;
- default:
- Log.e(TAG, "Incorrect state: " + state);
- break;
- }
- }
- }
-
- @VisibleForTesting
- class Connected extends State {
- @Override
- public void enter() {
- Log.i(TAG, "Enter Connected(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
- mConnectionState = BluetoothProfile.STATE_CONNECTED;
- removeDeferredMessages(CONNECT);
- broadcastConnectionState(BluetoothProfile.STATE_CONNECTED, mLastConnectionState);
- }
-
- @Override
- public void exit() {
- log("Exit Connected(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
- mLastConnectionState = BluetoothProfile.STATE_CONNECTED;
- }
-
- @Override
- public boolean processMessage(Message message) {
- log("Connected: process message(" + mDevice + "): "
- + messageWhatToString(message.what));
-
- switch (message.what) {
- case CONNECT:
- Log.w(TAG, "Connected: CONNECT ignored: " + mDevice);
- break;
- case DISCONNECT:
- log("Disconnecting from " + mDevice);
- if (!mNativeInterface.disconnectHapClient(mDevice)) {
- // If error in the native stack, transition directly to Disconnected state.
- Log.e(TAG, "Connected: error disconnecting from " + mDevice);
- transitionTo(mDisconnected);
- break;
- }
- transitionTo(mDisconnecting);
- break;
- case STACK_EVENT:
- HapClientStackEvent event = (HapClientStackEvent) message.obj;
- log("Connected: stack event: " + event);
- if (!mDevice.equals(event.device)) {
- Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event);
- }
- switch (event.type) {
- case HapClientStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
- processConnectionEvent(event.valueInt1);
- break;
- default:
- Log.e(TAG, "Connected: ignoring stack event: " + event);
- break;
- }
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- // in Connected state
- private void processConnectionEvent(int state) {
- switch (state) {
- case HapClientStackEvent.CONNECTION_STATE_DISCONNECTED:
- Log.i(TAG, "Disconnected from " + mDevice + " but still in Allowlist");
- transitionTo(mDisconnected);
- break;
- case HapClientStackEvent.CONNECTION_STATE_DISCONNECTING:
- Log.i(TAG, "Disconnecting from " + mDevice);
- transitionTo(mDisconnecting);
- break;
- default:
- Log.e(TAG, "Connection State Device: " + mDevice + " bad state: " + state);
- break;
- }
- }
- }
-}
diff --git a/src/com/android/bluetooth/hfp/HeadsetA2dpSync.java b/src/com/android/bluetooth/hfp/HeadsetA2dpSync.java
index 6a6a2ab13..b68a1854f 100644
--- a/src/com/android/bluetooth/hfp/HeadsetA2dpSync.java
+++ b/src/com/android/bluetooth/hfp/HeadsetA2dpSync.java
@@ -47,7 +47,6 @@ import java.lang.reflect.*;
import com.android.bluetooth.apm.ApmConstIntf;
import com.android.bluetooth.apm.ActiveDeviceManagerServiceIntf;
import com.android.bluetooth.apm.CallAudioIntf;
-import com.android.bluetooth.acm.AcmService;
/**
* Defines methods used for synchronization between HFP and A2DP
@@ -161,42 +160,6 @@ public class HeadsetA2dpSync {
}
}
- public void hfpCallBapMediaSync(boolean isBapMediaSuspend) {
- Log.d(TAG,"hfpCallBapMediaSync(): isBapMediaSuspend: " + isBapMediaSuspend);
- if (ApmConstIntf.getAospLeaEnabled()) {
- ActiveDeviceManagerServiceIntf mActiveDeviceManager =
- ActiveDeviceManagerServiceIntf.get();
- int MediaProfile =
- mActiveDeviceManager.getActiveProfile(ApmConstIntf.AudioFeatures.MEDIA_AUDIO);
- int VoiceProfile =
- mActiveDeviceManager.getActiveProfile(ApmConstIntf.AudioFeatures.CALL_AUDIO);
- BluetoothDevice mMediaDevice =
- mActiveDeviceManager.getActiveDevice(ApmConstIntf.AudioFeatures.MEDIA_AUDIO);
- BluetoothDevice mVoiceDevice =
- mActiveDeviceManager.getActiveDevice(ApmConstIntf.AudioFeatures.CALL_AUDIO);
- Log.d(TAG,"hfpCallBapMediaSync(): MediaProfile: " + MediaProfile +
- ", current active media device: " + mMediaDevice);
- Log.d(TAG,"hfpCallBapMediaSync: VoiceProfile: " + VoiceProfile +
- ", current active voice device: " + mVoiceDevice);
-
- if (MediaProfile != ApmConstIntf.AudioProfiles.NONE &&
- MediaProfile != ApmConstIntf.AudioProfiles.A2DP &&
- VoiceProfile != ApmConstIntf.AudioProfiles.NONE &&
- VoiceProfile == ApmConstIntf.AudioProfiles.HFP) {
- AcmService mAcmService = AcmService.getAcmService();
- if (mAcmService != null) {
- if (isBapMediaSuspend) {
- Log.d(TAG,"hfpCallBapMediaSync(): hfp call active, suspend bap Music ");
- mAcmService.hfpCallBapMediaSync(true);
- } else {
- Log.d(TAG,"hfpCallBapMediaSync(): hfp call ended, resume bap Music ");
- mAcmService.hfpCallBapMediaSync(false);
- }
- }
- }
- }
- }
-
public boolean suspendA2DP(int reason, BluetoothDevice device) {
int a2dpState = isA2dpPlaying();
String a2dpSuspendStatus;
@@ -317,7 +280,6 @@ public class HeadsetA2dpSync {
}
}
Log.d(TAG," A2DP Playing ,wait for suspend ");
- //hfpCallBapMediaSync(true);
return true;
}
return false;
@@ -377,7 +339,6 @@ public class HeadsetA2dpSync {
} else {
mSystemInterface.getAudioManager().setA2dpSuspended(false);
releaseLeAudio();
- //hfpCallBapMediaSync(false);
}
return true;
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetService.java b/src/com/android/bluetooth/hfp/HeadsetService.java
index 47b9b60c2..7b3e9d1c1 100644
--- a/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -46,11 +46,6 @@
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
- *
- * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- *
*/
package com.android.bluetooth.hfp;
@@ -99,17 +94,11 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.bluetooth.apm.DeviceProfileMapIntf;
import com.android.bluetooth.apm.ApmConstIntf;
-import com.android.bluetooth.apm.ApmConst;
import com.android.bluetooth.apm.CallAudioIntf;
import com.android.bluetooth.apm.CallControlIntf;
import com.android.bluetooth.apm.ActiveDeviceManagerServiceIntf;
import com.android.bluetooth.le_audio.LeAudioService;
import com.android.modules.utils.SynchronousResultReceiver;
-import com.android.bluetooth.cc.CCService;
-import com.android.bluetooth.acm.AcmService;
-import com.android.bluetooth.apm.StreamAudioService;
-import com.android.bluetooth.btservice.ActiveDeviceManager;
-import com.android.bluetooth.le_audio.LeAudioService;
import java.util.ArrayList;
import java.util.Arrays;
@@ -166,7 +155,6 @@ public class HeadsetService extends ProfileService {
private int mSetMaxConfig;
private BluetoothDevice mActiveDevice;
private BluetoothDevice mTempActiveDevice;
- private BluetoothDevice mTempDualModeActiveDevice;
private boolean mSHOStatus = false;
private AdapterService mAdapterService;
private DatabaseManager mDatabaseManager;
@@ -196,7 +184,6 @@ public class HeadsetService extends ProfileService {
private boolean mIsTwsPlusShoEnabled = false;
private vendorhfservice mVendorHf;
private Context mContext = null;
- private static final int BAP_CALL = 0x10;
private AudioServerStateCallback mServerStateCallback = new AudioServerStateCallback();
private static final int AUDIO_CONNECTION_DELAY_DEFAULT = 100;
private static final String ACTION_BATTERY_STATE_CHANGED = "android.bluetooth.action.BATTERY_STATE_CHANGED";
@@ -660,11 +647,6 @@ public class HeadsetService extends ProfileService {
mCallAudio.onAudioStateChange(device, mAudioState);
}
- public boolean isVoipLeaWarEnabled() {
- CallAudioIntf mCallAudio = CallAudioIntf.get();
- return mCallAudio.isVoipLeaWarEnabled();
- }
-
public void setIntentScoVolume(Intent intent) {
Log.w(TAG, "setIntentScoVolume");
synchronized (mStateMachines) {
@@ -707,24 +689,6 @@ public class HeadsetService extends ProfileService {
return mService;
}
- private boolean isAospLeaVoipWarEnabled() {
- boolean ret = false;
- if (ApmConstIntf.getAospLeaEnabled()) {
- CallAudioIntf mCallAudio = CallAudioIntf.get();
- ActiveDeviceManagerServiceIntf mActiveDeviceManager =
- ActiveDeviceManagerServiceIntf.get();
- if (mCallAudio.isVoipLeaWarEnabled() &&
- (mActiveDeviceManager.getActiveProfile(ApmConst.AudioFeatures.CALL_AUDIO)
- == ApmConst.AudioProfiles.BAP_CALL ||
- mActiveDeviceManager.getActiveProfile(ApmConst.AudioFeatures.CALL_AUDIO)
- == ApmConst.AudioProfiles.TMAP_CALL)) {
- ret = true;
- }
- }
- Log.i(TAG, "isAospLeaVoipWarEnabled: " + ret);
- return ret;
- }
-
@Override
public void connect(BluetoothDevice device, AttributionSource source,
SynchronousResultReceiver receiver) {
@@ -780,7 +744,7 @@ public class HeadsetService extends ProfileService {
SynchronousResultReceiver receiver) {
try {
List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>(0);
- if (ApmConstIntf.getQtiLeAudioEnabled() || isAospLeaVoipWarEnabled()) {
+ if (ApmConstIntf.getQtiLeAudioEnabled()) {
Log.d(TAG, "getConnectedDevicesWithAttribution(): Adv Audio enabled");
CallAudioIntf mCallAudio = CallAudioIntf.get();
if (mCallAudio != null) {
@@ -805,7 +769,7 @@ public class HeadsetService extends ProfileService {
AttributionSource source, SynchronousResultReceiver receiver) {
try {
List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>(0);
- if (ApmConstIntf.getQtiLeAudioEnabled() || isAospLeaVoipWarEnabled()) {
+ if (ApmConstIntf.getQtiLeAudioEnabled()) {
Log.d(TAG, "getDevicesMatchingConnectionStates(): Adv Audio enabled");
CallAudioIntf mCallAudio = CallAudioIntf.get();
defaultValue = mCallAudio.getDevicesMatchingConnectionStates(states);
@@ -979,7 +943,7 @@ public class HeadsetService extends ProfileService {
public void isAudioOn(AttributionSource source, SynchronousResultReceiver receiver) {
try {
boolean defaultValue = false;
- if(ApmConstIntf.getQtiLeAudioEnabled() || isAospLeaVoipWarEnabled()) {
+ if(ApmConstIntf.getQtiLeAudioEnabled()) {
Log.d(TAG, "isAudioOn(): Adv Audio enabled");
CallAudioIntf mCallAudio = CallAudioIntf.get();
defaultValue = mCallAudio.isAudioOn();
@@ -1016,8 +980,7 @@ public class HeadsetService extends ProfileService {
SynchronousResultReceiver receiver) {
try {
int defaultValue = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
- // Not fake getAudioState API for Aosp LeAudio VOIP WAR
- if (ApmConstIntf.getQtiLeAudioEnabled()) {
+ if(ApmConstIntf.getQtiLeAudioEnabled()) {
Log.d(TAG, "getAudioState(): Adv Audio enabled");
CallAudioIntf mCallAudio = CallAudioIntf.get();
defaultValue = mCallAudio.getAudioState(device);
@@ -1137,7 +1100,7 @@ public class HeadsetService extends ProfileService {
SynchronousResultReceiver receiver) {
try {
boolean defaultValue = false;
- if(ApmConstIntf.getQtiLeAudioEnabled() || isAospLeaVoipWarEnabled()) {
+ if(ApmConstIntf.getQtiLeAudioEnabled()) {
Log.d(TAG, "startScoUsingVirtualVoiceCall(): Adv Audio enabled");
CallAudioIntf mCallAudio = CallAudioIntf.get();
defaultValue = mCallAudio.startScoUsingVirtualVoiceCall();
@@ -1159,7 +1122,7 @@ public class HeadsetService extends ProfileService {
SynchronousResultReceiver receiver) {
try {
boolean defaultValue = false;
- if(ApmConstIntf.getQtiLeAudioEnabled() || isAospLeaVoipWarEnabled()) {
+ if(ApmConstIntf.getQtiLeAudioEnabled()) {
Log.d(TAG, "stopScoUsingVirtualVoiceCall(): Adv Audio enabled");
CallAudioIntf mCallAudio = CallAudioIntf.get();
defaultValue = mCallAudio.stopScoUsingVirtualVoiceCall();
@@ -1247,7 +1210,7 @@ public class HeadsetService extends ProfileService {
public void getActiveDevice(AttributionSource source, SynchronousResultReceiver receiver) {
try {
BluetoothDevice defaultValue = null;
- if(ApmConstIntf.getQtiLeAudioEnabled() || isAospLeaVoipWarEnabled()) {
+ if(ApmConstIntf.getQtiLeAudioEnabled()) {
ActiveDeviceManagerServiceIntf activeDeviceManager = ActiveDeviceManagerServiceIntf.get();
defaultValue = activeDeviceManager.getActiveAbsoluteDevice(ApmConstIntf.AudioFeatures.CALL_AUDIO);
receiver.send(defaultValue);
@@ -2394,39 +2357,7 @@ public class HeadsetService extends ProfileService {
}
if (mActiveDevice == null) {
Log.w(TAG, "startScoUsingVirtualVoiceCall: no active device");
- if (Utils.isDualModeAudioEnabled()) {
- Log.i(TAG, "Dual mode is enabled");
- ActiveDeviceManagerServiceIntf mActiveDeviceManager =
- ActiveDeviceManagerServiceIntf.get();
- StreamAudioService mStreamAudioService =
- StreamAudioService.getStreamAudioService();
- if (mActiveDeviceManager != null) {
- mTempDualModeActiveDevice =
- mActiveDeviceManager.getActiveAbsoluteDevice(ApmConstIntf.AudioFeatures.CALL_AUDIO);
- }
- if (mStreamAudioService != null) {
- Log.i(TAG, "Setting ACM null device");
- int ret =
- mStreamAudioService.setActiveDevice(null,
- BAP_CALL,
- false);
- mHfpA2dpSyncInterface.suspendLeAudio(HeadsetA2dpSync.
- A2DP_SUSPENDED_BY_CS_CALL);
- }
- if (mTempDualModeActiveDevice != null) {
- int ret = setActiveDeviceHF(mTempDualModeActiveDevice);
- if (ret == ActiveDeviceManagerServiceIntf.SHO_SUCCESS) {
- //Active device is set. Initiate SCO.
- Log.i(TAG, "active device is set. Initiate SCO");
- } else {
- return false;
- }
- } else {
- return false;
- }
- } else {
- return false;
- }
+ return false;
}
mVirtualCallStarted = true;
mSystemInterface.getHeadsetPhoneState().setIsCsCall(false);
@@ -2452,21 +2383,6 @@ public class HeadsetService extends ProfileService {
// 2. Send virtual phone state changed to close SCO
phoneStateChanged(0, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0, "", true);
}
- if (Utils.isDualModeAudioEnabled()) {
- StreamAudioService mStreamAudioService =
- StreamAudioService.getStreamAudioService();
- if (mTempDualModeActiveDevice != null) {
- if (mStreamAudioService != null) {
- Log.i(TAG, "Setting ACM device after voip");
- int ret =
- mStreamAudioService.setActiveDevice(mTempDualModeActiveDevice,
- BAP_CALL,
- false);
- }
- setActiveDeviceHF(null);
- mTempDualModeActiveDevice = null;
- }
- }
return true;
}
@@ -2763,15 +2679,6 @@ public class HeadsetService extends ProfileService {
Log.w(TAG, "mStateMachinesThread is null, returning");
return;
}
-
- if (isScoOrCallActive() &&
- (((numActive + numHeld) == 0) &&
- (callState == HeadsetHalConstants.CALL_STATE_IDLE))) {
- ActiveDeviceManager mDeviceManager =
- AdapterService.getAdapterService().getActiveDeviceManager();
- mDeviceManager.triggerPendingA2dpActiveDevice();
- }
-
// Should stop all other audio mode in this case
if ((numActive + numHeld) > 0 || callState != HeadsetHalConstants.CALL_STATE_IDLE) {
if (!isVirtualCall && mVirtualCallStarted) {
@@ -2938,32 +2845,9 @@ public class HeadsetService extends ProfileService {
int toState) {
synchronized (mStateMachines) {
List<BluetoothDevice> audioConnectableDevices =
- getConnectedDevices();
- CCService ccService = CCService.getCCService();
- AcmService acmService = AcmService.getAcmService();
- LeAudioService leAudioService = LeAudioService.getLeAudioService();
- List<BluetoothDevice> leaudioConnectedDevices = new ArrayList<>(0);
- List<BluetoothDevice> leAudioGroupLeadDevices = new ArrayList<>(0);
- if (acmService != null) {
- leaudioConnectedDevices = acmService.getConnectedDevices();
- Log.v(TAG, "onConnectionStateChanged: leAudioConnectedDevices = "
- + leaudioConnectedDevices.size());
- }
-
- if (leAudioService != null) {
- leAudioGroupLeadDevices = leAudioService.getConnectedGroupLeadDevices();
- Log.v(TAG, "onConnectionStateChanged: leAudioGroupLeadDevices = "
- + leAudioGroupLeadDevices.size());
- }
-
+ getConnectedDevices();
if (fromState != BluetoothProfile.STATE_CONNECTED
&& toState == BluetoothProfile.STATE_CONNECTED) {
- if (ccService != null) {
- if ((leAudioGroupLeadDevices.size() >= 1) && ccService.isInbandRingingEnabled()) {
- Log.i(TAG,"Disable Inband Ringtone for CC if hf device also connected");
- ccService.updateStatusFlags(0);
- }
- }
boolean isInbandRingingSupported = getResources().getBoolean(
com.android.bluetooth.R.bool.config_bluetooth_hfp_inband_ringing_support);
if (audioConnectableDevices.size() > 1 && isInbandRingingSupported &&
@@ -2979,12 +2863,6 @@ public class HeadsetService extends ProfileService {
&& toState == BluetoothProfile.STATE_DISCONNECTED) {
if (audioConnectableDevices.size() <= 1 ) {
mInbandRingingRuntimeDisable = false;
- if (ccService != null) {
- if (leAudioGroupLeadDevices.size() <= 1 && ccService.isInbandRingingEnabled()) {
- Log.i(TAG,"enable Inband Ringtone for CC if hf device is disconnected");
- ccService.updateStatusFlags(1);
- }
- }
}
if (device.equals(mActiveDevice)) {
AdapterService adapterService = AdapterService.getAdapterService();
diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index 59d264685..36a8e4971 100644
--- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -46,11 +46,6 @@
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
- *
- * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- *
*/
package com.android.bluetooth.hfp;
@@ -515,8 +510,7 @@ public class HeadsetStateMachine extends StateMachine {
mHeadsetService.updateConnState(device, toState);
}
mHeadsetService.onConnectionStateChangedFromStateMachine(device, fromState, toState);
- if(!ApmConstIntf.getQtiLeAudioEnabled() &&
- !(ApmConstIntf.getAospLeaEnabled() && mHeadsetService.isVoipLeaWarEnabled())) {
+ if(!ApmConstIntf.getQtiLeAudioEnabled()) {
Intent intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, fromState);
intent.putExtra(BluetoothProfile.EXTRA_STATE, toState);
diff --git a/src/com/android/bluetooth/le_audio/LeAudioService.java b/src/com/android/bluetooth/le_audio/LeAudioService.java
index 886bc2ff2..da12310db 100644
--- a/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -13,11 +13,6 @@
* 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.
- *
- * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- *
*/
package com.android.bluetooth.le_audio;
@@ -69,7 +64,6 @@ import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ServiceFactory;
-import com.android.bluetooth.hap.HapClientService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.csip.CsipSetCoordinatorService;
@@ -82,13 +76,11 @@ import com.android.modules.utils.SynchronousResultReceiver;
import com.android.bluetooth.apm.ActiveDeviceManagerServiceIntf;
import com.android.bluetooth.apm.ApmConstIntf;
-import com.android.bluetooth.apm.ApmConst;
import com.android.bluetooth.apm.MediaAudioIntf;
import com.android.bluetooth.apm.CallAudioIntf;
import com.android.bluetooth.apm.VolumeManagerIntf;
import com.android.bluetooth.acm.AcmServIntf;
import com.android.internal.util.ArrayUtils;
-import com.android.bluetooth.apm.DeviceProfileMap;
import java.util.Arrays;
import java.math.BigInteger;
@@ -161,7 +153,6 @@ public class LeAudioService extends ProfileService {
private HandlerThread mStateMachinesThread;
private BluetoothDevice mActiveAudioOutDevice;
private BluetoothDevice mActiveAudioInDevice;
- private static BluetoothDevice mPreviousActiveDevice;
private int mLeActiveGroupID;
private LeAudioCodecConfig mLeAudioCodecConfig;
ServiceFactory mServiceFactory = new ServiceFactory();
@@ -377,7 +368,6 @@ public class LeAudioService extends ProfileService {
mStateMachines.clear();
}*/
- mPreviousActiveDevice = null;
mDeviceGroupIdMap.clear();
mDeviceAudioLocationMap.clear();
mGroupDescriptors.clear();
@@ -494,13 +484,9 @@ public class LeAudioService extends ProfileService {
}
}
- if (!mPtsTmapConfBandC &&
- mPtsMediaAndVoice == 2) {
+ if (!mPtsTmapConfBandC && mPtsMediaAndVoice == 2) {
if (mCallAudio != null) {
- Log.d(TAG, "connect(): Connecting call AUdio");
mCallAudio.connect(device);
- } else {
- Log.d(TAG, "call AUdio is null");
}
}
@@ -1178,139 +1164,23 @@ public class LeAudioService extends ProfileService {
setActiveDeviceGroup(device);
return true;
}*/
- Log.d(TAG, "setActiveDevice() for device: " + device +
- ", mPreviousActiveDevice: " + mPreviousActiveDevice);
- DeviceProfileMap dpm = DeviceProfileMap.getDeviceProfileMapInstance();
- if (dpm == null) {
- Log.w(TAG, "setActiveDevice: dpm is null, return.");
- return false;
- }
- BluetoothDevice fetchCurrentActiveDevice = null;
-
- if (device == null) {
- fetchCurrentActiveDevice = mPreviousActiveDevice;
- mPreviousActiveDevice = null;
- } else {
- fetchCurrentActiveDevice = device;
- }
-
- int MediaProfID = dpm.getSupportedProfile(fetchCurrentActiveDevice,
- ApmConst.AudioFeatures.MEDIA_AUDIO);
- int VoiceProfID = dpm.getSupportedProfile(fetchCurrentActiveDevice,
- ApmConst.AudioFeatures.CALL_AUDIO);
- Log.d(TAG, "setActiveDevice: "+ " MediaProfID:" + MediaProfID +
- ", VoiceProfID:" + VoiceProfID);
-
- mPreviousActiveDevice = device;
- CallAudioIntf mCallAudio = CallAudioIntf.get();
- boolean isInCall =
- mCallAudio != null && mCallAudio.isVoiceOrCallActive();
- int adapterState = (mAdapterService != null) ? mAdapterService.getState()
- : BluetoothAdapter.STATE_OFF;
- Log.d(TAG, "setActiveDevice: "+ " adapterState: " + adapterState);
-
- boolean isDuMoEnabled = Utils.isDualModeAudioEnabled();
ActiveDeviceManagerServiceIntf activeDeviceManager =
ActiveDeviceManagerServiceIntf.get();
- if (device == null || ((ApmConst.AudioProfiles.HAP_LE & VoiceProfID) ==
- ApmConst.AudioProfiles.HAP_LE) ||
- ((ApmConst.AudioProfiles.BAP_CALL & VoiceProfID) ==
- ApmConst.AudioProfiles.BAP_CALL)) {
- if (isInCall && adapterState == BluetoothAdapter.STATE_ON) {
- if (isDuMoEnabled) {
- Log.d(TAG, "Telephony request for Active device, DualMode");
- activeDeviceManager.setActiveDevice(device,
- ApmConstIntf.AudioFeatures.CALL_AUDIO, true);
- } else {
- activeDeviceManager.setActiveDeviceBlocking(device,
- ApmConstIntf.AudioFeatures.CALL_AUDIO);
- }
- } else {
- activeDeviceManager.setActiveDevice(device,
- ApmConstIntf.AudioFeatures.CALL_AUDIO);
- }
- }
-
- if (device == null || ((ApmConst.AudioProfiles.HAP_LE & MediaProfID) ==
- ApmConst.AudioProfiles.HAP_LE) ||
- ((ApmConst.AudioProfiles.BAP_MEDIA & MediaProfID) ==
- ApmConst.AudioProfiles.BAP_MEDIA)) {
- if (isInCall && adapterState == BluetoothAdapter.STATE_ON) {
- if (isDuMoEnabled) {
- activeDeviceManager.setActiveDevice(device,
- ApmConstIntf.AudioFeatures.MEDIA_AUDIO, true);
- } else {
- activeDeviceManager.setActiveDeviceBlocking(device,
- ApmConstIntf.AudioFeatures.MEDIA_AUDIO);
- }
- } else {
- Log.d(TAG, "Telephony request for Active device, DualMode");
- activeDeviceManager.setActiveDevice(device,
- ApmConstIntf.AudioFeatures.MEDIA_AUDIO);
- }
- }
+ activeDeviceManager.setActiveDevice(device,
+ ApmConstIntf.AudioFeatures.CALL_AUDIO);
+ activeDeviceManager.setActiveDevice(device,
+ ApmConstIntf.AudioFeatures.MEDIA_AUDIO);
return true;
}
public boolean setActiveDeviceBlocking(BluetoothDevice device) {
- Log.d(TAG, "setActiveDeviceBlocking() for device: " + device +
- ", mPreviousActiveDevice: " + mPreviousActiveDevice);
- DeviceProfileMap dpm = DeviceProfileMap.getDeviceProfileMapInstance();
- if (dpm == null) {
- Log.w(TAG, "setActiveDeviceBlocking: dpm is null, return.");
- return false;
- }
- BluetoothDevice fetchCurrentActiveDevice = null;
- boolean isDuMoEnabled = Utils.isDualModeAudioEnabled();
-
- if (device == null) {
- fetchCurrentActiveDevice = mPreviousActiveDevice;
- mPreviousActiveDevice = null;
- } else {
- fetchCurrentActiveDevice = device;
- }
-
- Log.d(TAG, "setActiveDeviceBlocking(): fetchCurrentActiveDevice: " +
- fetchCurrentActiveDevice);
-
- int MediaProfID = dpm.getSupportedProfile(fetchCurrentActiveDevice,
- ApmConst.AudioFeatures.MEDIA_AUDIO);
- int VoiceProfID = dpm.getSupportedProfile(fetchCurrentActiveDevice,
- ApmConst.AudioFeatures.CALL_AUDIO);
- Log.d(TAG, "setActiveDeviceBlocking: "+ " MediaProfID:" + MediaProfID +
- ", VoiceProfID:" + VoiceProfID);
- mPreviousActiveDevice = device;
-
+ Log.d(TAG, "setActiveDeviceBlocking() for device: " + device);
ActiveDeviceManagerServiceIntf activeDeviceManager =
ActiveDeviceManagerServiceIntf.get();
-
- if (device == null || ((ApmConst.AudioProfiles.HAP_LE & VoiceProfID) ==
- ApmConst.AudioProfiles.HAP_LE) ||
- ((ApmConst.AudioProfiles.BAP_CALL & VoiceProfID) ==
- ApmConst.AudioProfiles.BAP_CALL)) {
- if (isDuMoEnabled) {
- Log.d(TAG, " Avoiding Blocking call for DUMO");
- activeDeviceManager.setActiveDevice(device,
- ApmConstIntf.AudioFeatures.CALL_AUDIO);
- } else {
- activeDeviceManager.setActiveDeviceBlocking(device,
+ activeDeviceManager.setActiveDeviceBlocking(device,
ApmConstIntf.AudioFeatures.CALL_AUDIO);
- }
- }
-
- if (device == null || ((ApmConst.AudioProfiles.HAP_LE & MediaProfID) ==
- ApmConst.AudioProfiles.HAP_LE) ||
- ((ApmConst.AudioProfiles.BAP_MEDIA & MediaProfID) ==
- ApmConst.AudioProfiles.BAP_MEDIA)) {
- if (isDuMoEnabled) {
- Log.d(TAG, " Avoiding Blocking call for DUMO");
- activeDeviceManager.setActiveDevice(device,
- ApmConstIntf.AudioFeatures.MEDIA_AUDIO);
- } else {
- activeDeviceManager.setActiveDeviceBlocking(device,
+ activeDeviceManager.setActiveDeviceBlocking(device,
ApmConstIntf.AudioFeatures.MEDIA_AUDIO);
- }
- }
return true;
}
@@ -1340,13 +1210,6 @@ public class LeAudioService extends ProfileService {
activeDevices.add(1, mActiveAudioInDevice);
}*/
- activeDevices.add(0, null);
- activeDevices.add(1, null);
- if (ApmConstIntf.getQtiLeAudioEnabled()) {
- Log.d(TAG, "QTI LeAudio is enabled, return empty list");
- return activeDevices;
- }
-
ActiveDeviceManagerServiceIntf activeDeviceManager =
ActiveDeviceManagerServiceIntf.get();
BluetoothDevice outDevice = activeDeviceManager.getActiveAbsoluteDevice(ApmConstIntf.AudioFeatures.MEDIA_AUDIO);
@@ -1364,21 +1227,13 @@ public class LeAudioService extends ProfileService {
mActiveAudioInDevice =
activeDeviceManager.getActiveAbsoluteDevice(ApmConstIntf.AudioFeatures.CALL_AUDIO);
*/
- int ActiveAudioMediaProfile =
- activeDeviceManager.getActiveProfile(ApmConstIntf.AudioFeatures.MEDIA_AUDIO);
- int ActiveAudioCallProfile =
- activeDeviceManager.getActiveProfile(ApmConstIntf.AudioFeatures.CALL_AUDIO);
-
/*if (ActiveAudioMediaProfile == ApmConst.AudioProfiles.TMAP_MEDIA ||
ActiveAudioMediaProfile == ApmConst.AudioProfiles.BAP_MEDIA ||
ActiveAudioMediaProfile == ApmConst.AudioProfiles.BAP_GCP ||
ActiveAudioMediaProfile == ApmConst.AudioProfiles.BAP_GCP_VBC ||
ActiveAudioCallProfile == ApmConst.AudioProfiles.TMAP_CALL ||
- ActiveAudioCallProfile == ApmConst.AudioProfiles.BAP_CALL) {
- if (ActiveAudioCallProfile != ApmConst.AudioProfiles.HFP) {
- activeDevices.add(0, mActiveAudioOutDevice);
- }
- }
+ ActiveAudioCallProfile == ApmConst.AudioProfiles.BAP_CALL)
+ activeDevices.add(0, mActiveAudioOutDevice);
if (ActiveAudioMediaProfile == ApmConst.AudioProfiles.BAP_RECORDING ||
ActiveAudioMediaProfile == ApmConst.AudioProfiles.BAP_GCP_VBC ||
@@ -1393,12 +1248,6 @@ public class LeAudioService extends ProfileService {
activeDevices.add(1, mActiveAudioInDevice);
}
}*/
-
- if ((ActiveAudioMediaProfile == ApmConst.AudioProfiles.BROADCAST_LE) &&
- (ActiveAudioCallProfile == ApmConst.AudioProfiles.TMAP_CALL ||
- ActiveAudioCallProfile == ApmConst.AudioProfiles.BAP_CALL)) {
- mActiveAudioOutDevice = mActiveAudioInDevice;
- }
activeDevices.add(0, mActiveAudioOutDevice);
int activeGid = getGroupId(mActiveAudioOutDevice);
if (activeGid < INVALID_SET_ID) {
@@ -2076,17 +1925,6 @@ public class LeAudioService extends ProfileService {
Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy);
}
- ParcelUuid[] featureUuids = mAdapterService.getRemoteUuids(device);
- if (ArrayUtils.contains(featureUuids, BluetoothUuid.HAS)) {
- Log.e(TAG, ": Remote has Hearing Aid UUID");
- //Calling HapClient Setconnection policy
- HapClientService hapClientService = HapClientService.getHapClientService();
- if (hapClientService != null) {
- hapClientService.setConnectionPolicy(device, connectionPolicy);
- Log.d(TAG, "Hap connectionPolicy ");
- }
- }
-
if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO,
connectionPolicy)) {
return false;
@@ -2680,50 +2518,12 @@ public class LeAudioService extends ProfileService {
boolean defaultValueVoice = false;
boolean defaultValueMedia = false;
if (service != null) {
- Log.d(TAG, "Binder setActiveDevice() for device: " + device +
- ", mPreviousActiveDevice: " + mPreviousActiveDevice);
ActiveDeviceManagerServiceIntf activeDeviceManager =
ActiveDeviceManagerServiceIntf.get();
- DeviceProfileMap dpm = DeviceProfileMap.getDeviceProfileMapInstance();
- if (dpm == null) {
- Log.w(TAG, "Binder setActiveDevice: dpm is null, return.");
- return;
- }
-
- BluetoothDevice fetchCurrentActiveDevice = null;
-
- if (device == null) {
- fetchCurrentActiveDevice = mPreviousActiveDevice;
- mPreviousActiveDevice = null;
- } else {
- fetchCurrentActiveDevice = device;
- }
-
- int MediaProfID = dpm.getSupportedProfile(fetchCurrentActiveDevice,
- ApmConst.AudioFeatures.MEDIA_AUDIO);
- int VoiceProfID = dpm.getSupportedProfile(fetchCurrentActiveDevice,
- ApmConst.AudioFeatures.CALL_AUDIO);
- Log.d(TAG, "Binder setActiveDevice: "+ " MediaProfID:" + MediaProfID +
- ", VoiceProfID:" + VoiceProfID);
-
- mPreviousActiveDevice = device;
-
- if (((ApmConst.AudioProfiles.HAP_LE & VoiceProfID) ==
- ApmConst.AudioProfiles.HAP_LE) ||
- ((ApmConst.AudioProfiles.BAP_CALL & VoiceProfID) ==
- ApmConst.AudioProfiles.BAP_CALL)) {
- defaultValueVoice = activeDeviceManager.setActiveDevice(device,
- ApmConstIntf.AudioFeatures.CALL_AUDIO, true);
- }
-
- if (((ApmConst.AudioProfiles.HAP_LE & MediaProfID) ==
- ApmConst.AudioProfiles.HAP_LE) ||
- ((ApmConst.AudioProfiles.BAP_MEDIA & MediaProfID) ==
- ApmConst.AudioProfiles.BAP_MEDIA)) {
- defaultValueMedia = activeDeviceManager.setActiveDevice(device,
- ApmConstIntf.AudioFeatures.MEDIA_AUDIO, true);
- }
-
+ defaultValueVoice = activeDeviceManager.setActiveDevice(device,
+ ApmConstIntf.AudioFeatures.CALL_AUDIO, true);
+ defaultValueMedia = activeDeviceManager.setActiveDevice(device,
+ ApmConstIntf.AudioFeatures.MEDIA_AUDIO, true);
defaultValue = (defaultValueVoice & defaultValueMedia);
}
receiver.send(defaultValue);
diff --git a/114.json b/tests/unit/src/com/android/bluetooth/btservice/storage/schemas/com.android.bluetooth.btservice.storage.MetadataDatabase/114.json
index 64f8ab3fd..64f8ab3fd 100644
--- a/114.json
+++ b/tests/unit/src/com/android/bluetooth/btservice/storage/schemas/com.android.bluetooth.btservice.storage.MetadataDatabase/114.json