知方号

知方号

A2DP Hardware Offload<卸载是什么意思>

关于A2DP硬件卸载功能,描述可以看https://source.android.com/docs/core/connect/bluetooth/hci_requirements#a2dp-hardware-offload-support。

如我在Android Bluetooth A2DP_阅后即奋的博客-CSDN博客中的3.2.7节所述,Audio Stream通过Audio处理器直接发给了BT控制器。

1. 功能开关 1.1 UI开关

继续以Android手机为例,该功能的开关,可以开发者选项中看到开关。

 默认地,停用蓝牙A2DP硬件卸载功能是关闭的,双重否定即肯定,那么这里的意思就是默认支持A2DP Hardware Offload功能,也就是前面所述Audio Stream通过Audio处理器直接发给了BT控制器。

1.2 Code Check

判断是否使能A2DP Hardware Offload功能。

// packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java // a2dp offload是否禁用 private static final String A2DP_OFFLOAD_DISABLED_PROPERTY = "persist.bluetooth.a2dp_offload.disabled"; // a2dp offload是否支持 private static final String A2DP_OFFLOAD_SUPPORTED_PROPERTY = "ro.bluetooth.a2dp_offload.supported"; // 请斟酌使能和支持的区别 public void init(RemoteDevices remoteDevices) { // ...... mA2dpOffloadEnabled = SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false) && !SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false); // ...... } /** * @return A2DP offload support */ boolean isA2dpOffloadEnabled() { return mA2dpOffloadEnabled; }

2. 日志分析。

资源下载:https://download.csdn.net/download/hihan_5/87108298

下面的日志,表示Audio Source设备不支持Bluetooth Broadcast Audio profile。

11-21 16:15:17.255 1002 13479 13515 D A2dpService: setActiveDevice: BA active false11-21 16:15:17.255 1002 13479 13515 D A2dpService: Switch A2DP devices to CC:98:8B:57:23:39 from null11-21 16:15:17.255 1002 13479 13515 W A2dpService: setActiveDevice coming out of mutex lock11-21 16:15:17.256 1002 13479 13515 I BluetoothA2dpServiceJni: setActiveDeviceNative: sBluetoothA2dpInterface: 0x7d043e3d30 // packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java// vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java private boolean setActiveDeviceInternal(BluetoothDevice device) { // ....... try { mA2dpNativeInterfaceLock.readLock().lock(); if (mA2dpNativeInterface != null && !mA2dpNativeInterface.setActiveDevice(device)) { Log.e(TAG, "setActiveDevice(" + device + "): Cannot set as active in native layer"); return false; } } finally { mA2dpNativeInterfaceLock.readLock().unlock(); } // ...... }

mA2dpNativeInterface.setActiveDevice(device)调用Native函数。

// packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cpp// vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cppstatic jboolean setActiveDeviceNative(JNIEnv* env, jobject object, jbyteArray address) { ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); std::shared_lock lock(interface_mutex); if (!sBluetoothA2dpInterface) { ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); RawAddress bd_addr = RawAddress::kEmpty; if (addr) { bd_addr.FromOctets(reinterpret_cast(addr)); } bt_status_t status = sBluetoothA2dpInterface->set_active_device(bd_addr); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed A2DP set_active_device, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;}static void initNative(JNIEnv* env, jobject object, jint maxConnectedAudioDevices, jobjectArray codecConfigArray, jobjectArray codecConfigOffload) {// ...... const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { ALOGE("%s: Bluetooth module is not loaded", __func__); return; }// ...... sBluetoothA2dpInterface = (btav_source_interface_t *)btInf->get_profile_interface( BT_PROFILE_ADVANCED_AUDIO_ID);// ...... bt_status_t status = sBluetoothA2dpInterface->init( &sBluetoothA2dpCallbacks, maxConnectedAudioDevices, codec_priorities, codec_offloading);// ......}

这里面重点是找到sBluetoothA2dpInterface指向谁?JNI函数初始化时会执行initNative,这里进行了sBluetoothA2dpInterface的赋值,然后执行了init函数。

先看btInf的指向。

// packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp// vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cppconst bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; }static void classInitNative(JNIEnv* env, jclass clazz) {//...... if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) { ALOGE("No Bluetooth Library found"); }}int hal_util_load_bt_library(const bt_interface_t** interface) { // #define BLUETOOTH_INTERFACE_STRING "bluetoothInterface" const char* sym = BLUETOOTH_INTERFACE_STRING; bt_interface_t* itf = nullptr; // The library name is not set by default, so the preset library name is used. char path[PROPERTY_VALUE_MAX] = ""; // 高通机型,这里加载了libbluetooth_qti.so // 非高通机型,例如MTK,加载libbluetooth.so property_get(PROPERTY_BT_LIBRARY_NAME, path, DEFAULT_BT_LIBRARY_NAME); void* handle = dlopen(path, RTLD_NOW); if (!handle) { const char* err_str = dlerror(); LOG(ERROR)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。