Loading android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -95,7 +95,8 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { } void OnDeviceAvailable(const RawAddress& bd_addr, int group_id, int group_size, const bluetooth::Uuid& uuid) override { int group_size, int rank, const bluetooth::Uuid& uuid) override { std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; Loading @@ -111,7 +112,7 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDeviceAvailable, addr.get(), (jint)group_id, (jint)group_size, UUID_PARAMS(uuid)); (jint)rank, UUID_PARAMS(uuid)); } void OnSetMemberAvailable(const RawAddress& bd_addr, int group_id) override { Loading Loading @@ -156,7 +157,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) { env->GetMethodID(clazz, "onConnectionStateChanged", "([BI)V"); method_onDeviceAvailable = env->GetMethodID(clazz, "onDeviceAvailable", "([BIIJJ)V"); env->GetMethodID(clazz, "onDeviceAvailable", "([BIIIJJ)V"); method_onSetMemberAvailable = env->GetMethodID(clazz, "onSetMemberAvailable", "([BI)V"); Loading android/app/jni/com_android_bluetooth_gatt.cpp +27 −14 Original line number Diff line number Diff line Loading @@ -16,17 +16,18 @@ #define LOG_TAG "BtGatt.JNI" #include "com_android_bluetooth.h" #include "hardware/bt_gatt.h" #include "utils/Log.h" #include <base/bind.h> #include <base/callback.h> #include <cutils/log.h> #include <string.h> #include <array> #include <memory> #include <shared_mutex> #include <cutils/log.h> #include "com_android_bluetooth.h" #include "hardware/bt_gatt.h" #include "utils/Log.h" #define info(fmt, ...) ALOGI("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) #define debug(fmt, ...) \ ALOGD("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) Loading Loading @@ -191,6 +192,7 @@ static const btgatt_interface_t* sGattIf = NULL; static jobject mCallbacksObj = NULL; static jobject mAdvertiseCallbacksObj = NULL; static jobject mPeriodicScanCallbacksObj = NULL; static std::shared_mutex callbacks_mutex; /** * BTA client callbacks Loading Loading @@ -802,8 +804,9 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnAdvertisingSetStarted(int reg_id, uint8_t advertiser_id, int8_t tx_power, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingSetStarted, reg_id, advertiser_id, tx_power, status); Loading @@ -811,24 +814,27 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingEnabled, advertiser_id, enable, status); } void OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingDataSet, advertiser_id, status); } void OnScanResponseDataSet(uint8_t advertiser_id, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onScanResponseDataSet, advertiser_id, status); Loading @@ -836,8 +842,9 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t tx_power, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingParametersUpdated, advertiser_id, tx_power, status); Loading @@ -845,16 +852,18 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onPeriodicAdvertisingParametersUpdated, advertiser_id, status); } void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onPeriodicAdvertisingDataSet, advertiser_id, status); Loading @@ -862,8 +871,9 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onPeriodicAdvertisingEnabled, advertiser_id, enable, status); Loading @@ -871,8 +881,9 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type, RawAddress address) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; ScopedLocalRef<jstring> addr(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &address)); Loading Loading @@ -1998,6 +2009,7 @@ static void advertiseClassInitNative(JNIEnv* env, jclass clazz) { } static void advertiseInitializeNative(JNIEnv* env, jobject object) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); if (mAdvertiseCallbacksObj != NULL) { ALOGW("Cleaning up Advertise callback object"); env->DeleteGlobalRef(mAdvertiseCallbacksObj); Loading @@ -2008,6 +2020,7 @@ static void advertiseInitializeNative(JNIEnv* env, jobject object) { } static void advertiseCleanupNative(JNIEnv* env, jobject object) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); if (mAdvertiseCallbacksObj != NULL) { env->DeleteGlobalRef(mAdvertiseCallbacksObj); mAdvertiseCallbacksObj = NULL; Loading android/app/src/com/android/bluetooth/a2dp/A2dpService.java +0 −8 Original line number Diff line number Diff line Loading @@ -1471,10 +1471,6 @@ public class A2dpService extends ProfileService { A2dpService service = getService(source); BluetoothCodecStatus codecStatus = null; if (service != null) { if (checkCallerTargetSdk(mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) { enforceBluetoothPrivilegedPermission(service); } codecStatus = service.getCodecStatus(device); } receiver.send(codecStatus); Loading @@ -1490,10 +1486,6 @@ public class A2dpService extends ProfileService { if (service == null) { return; } if (checkCallerTargetSdk(mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) { enforceBluetoothPrivilegedPermission(service); } service.setCodecConfigPreference(device, codecConfig); } Loading android/app/src/com/android/bluetooth/bass_client/BassClientService.java +6 −24 Original line number Diff line number Diff line Loading @@ -83,7 +83,6 @@ public class BassClientService extends ProfileService { private Map<BluetoothDevice, Integer> mDeviceToSyncHandleMap; /*syncHandle, parsed BaseData data*/ private Map<Integer, BaseData> mSyncHandleToBaseDataMap; private Map<Integer, BluetoothLeBroadcastMetadata> mBroadcastSources; /*bcastSrcDevice, corresponding PeriodicAdvertisementResult*/ private Map<BluetoothDevice, PeriodicAdvertisementResult> mPeriodicAdvertisementResultMap; private ScanCallback mSearchScanCallback; Loading Loading @@ -181,25 +180,6 @@ public class BassClientService extends ProfileService { return base; } void updateSourceInternal(int sourceId, BluetoothLeBroadcastMetadata metaData) { if (mBroadcastSources == null) { return; } if (metaData != null) { // This will replace old metadata with new one mBroadcastSources.put(sourceId, metaData); } else { mBroadcastSources.remove(sourceId); } } BluetoothLeBroadcastMetadata getSourceInternal(int sourceId) { if (mBroadcastSources != null) { return mBroadcastSources.get(sourceId); } return null; } void setActiveSyncedSource(BluetoothDevice scanDelegator, BluetoothDevice sourceDevice) { log("setActiveSyncedSource: scanDelegator" + scanDelegator + ":: sourceDevice:" + sourceDevice); Loading Loading @@ -283,10 +263,6 @@ public class BassClientService extends ProfileService { mActiveSourceMap.clear(); mActiveSourceMap = null; } if (mBroadcastSources != null) { mBroadcastSources.clear(); mBroadcastSources = null; } if (mBassUtils != null) { mBassUtils.cleanUp(); mBassUtils = null; Loading Loading @@ -765,6 +741,9 @@ public class BassClientService extends ProfileService { BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR); return; } if (stateMachine.hasPendingSourceOperation()) { throw new IllegalStateException("addSource: source operation already pending"); } if (!hasRoomForBroadcastSourceAddition(sink)) { log("addSource: device has no room"); mCallbacks.notifySourceAddFailed(sink, sourceMetadata, Loading Loading @@ -808,6 +787,9 @@ public class BassClientService extends ProfileService { BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR); return; } if (stateMachine.hasPendingSourceOperation()) { throw new IllegalStateException("modifySource: source operation already pending"); } Message message = stateMachine.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE); message.arg1 = sourceId; message.obj = updatedMetadata; Loading android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +59 −8 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ */ package com.android.bluetooth.bass_client; import static android.Manifest.permission.BLUETOOTH_CONNECT; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; Loading @@ -65,6 +67,7 @@ import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothLeAudioCodecConfigMetadata; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastAssistant; import android.bluetooth.BluetoothLeBroadcastChannel; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; Loading @@ -76,6 +79,7 @@ import android.bluetooth.le.PeriodicAdvertisingManager; import android.bluetooth.le.PeriodicAdvertisingReport; import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; import android.content.Intent; import android.os.Binder; import android.os.Looper; import android.os.Message; Loading @@ -83,6 +87,7 @@ import android.os.ParcelUuid; import android.provider.DeviceConfig; import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -136,6 +141,7 @@ public class BassClientStateMachine extends StateMachine { private final Map<Integer, BluetoothLeBroadcastReceiveState> mBluetoothLeBroadcastReceiveStates = new HashMap<Integer, BluetoothLeBroadcastReceiveState>(); private final Map<Integer, BluetoothLeBroadcastMetadata> mCurrentMetadata = new HashMap(); private final Disconnected mDisconnected = new Disconnected(); private final Connected mConnected = new Connected(); private final Connecting mConnecting = new Connecting(); Loading Loading @@ -236,6 +242,24 @@ public class BassClientStateMachine extends StateMachine { mPendingOperation = -1; mPendingSourceId = -1; mPendingMetadata = null; mCurrentMetadata.clear(); } Boolean hasPendingSourceOperation() { return mPendingMetadata != null; } BluetoothLeBroadcastMetadata getCurrentBroadcastMetadata(Integer sourceId) { return mCurrentMetadata.getOrDefault(sourceId, null); } private void setCurrentBroadcastMetadata(Integer sourceId, BluetoothLeBroadcastMetadata metadata) { if (metadata != null) { mCurrentMetadata.put(sourceId, metadata); } else { mCurrentMetadata.remove(sourceId); } } BluetoothLeBroadcastReceiveState getBroadcastReceiveStateForSourceDevice( Loading Loading @@ -724,7 +748,7 @@ public class BassClientStateMachine extends StateMachine { mService.getCallbacks().notifySourceAdded(mDevice, recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); if (mPendingMetadata != null) { mService.updateSourceInternal(recvState.getSourceId(), mPendingMetadata); setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata); } checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); Loading @@ -734,13 +758,13 @@ public class BassClientStateMachine extends StateMachine { BluetoothDevice removedDevice = oldRecvState.getSourceDevice(); log("sourceInfo removal" + removedDevice); cancelActiveSync(removedDevice); mService.updateSourceInternal(oldRecvState.getSourceId(), null); setCurrentBroadcastMetadata(oldRecvState.getSourceId(), null); mService.getCallbacks().notifySourceRemoved(mDevice, oldRecvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); } else { log("update to an existing recvState"); mService.updateSourceInternal(recvState.getSourceId(), mPendingMetadata); setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata); mService.getCallbacks().notifySourceModified(mDevice, recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); checkAndUpdateBroadcastCode(recvState); Loading Loading @@ -959,6 +983,7 @@ public class BassClientStateMachine extends StateMachine { } mPendingOperation = -1; mPendingMetadata = null; mCurrentMetadata.clear(); } @VisibleForTesting Loading @@ -975,6 +1000,16 @@ public class BassClientStateMachine extends StateMachine { } else { broadcastConnectionState( mDevice, mLastConnectionState, BluetoothProfile.STATE_DISCONNECTED); if (mLastConnectionState != BluetoothProfile.STATE_DISCONNECTED) { // Reconnect in background if not disallowed by the service if (mService.okToConnect(mDevice)) { mBluetoothGatt = mDevice.connectGatt(mService, true, mGattCallback, BluetoothDevice.TRANSPORT_LE, (BluetoothDevice.PHY_LE_1M_MASK | BluetoothDevice.PHY_LE_2M_MASK | BluetoothDevice.PHY_LE_CODED_MASK), null); } } } } Loading Loading @@ -1011,7 +1046,15 @@ public class BassClientStateMachine extends StateMachine { } break; case DISCONNECT: Log.w(TAG, "Disconnected: DISCONNECT ignored: " + mDevice); // Disconnect if there's an ongoing background connection if (mBluetoothGatt != null) { log("Cancelling the background connection to " + mDevice); mBluetoothGatt.disconnect(); mBluetoothGatt.close(); mBluetoothGatt = null; } else { Log.d(TAG, "Disconnected: DISCONNECT ignored: " + mDevice); } break; case CONNECTION_STATE_CHANGED: int state = (int) message.obj; Loading Loading @@ -1289,8 +1332,8 @@ public class BassClientStateMachine extends StateMachine { res[1] = (byte) recvState.getSourceId(); log("convertRecvStateToSetBroadcastCodeByteArray: Source device : " + recvState.getSourceDevice()); BluetoothLeBroadcastMetadata metaData = mService.getSourceInternal( recvState.getSourceId()); BluetoothLeBroadcastMetadata metaData = getCurrentBroadcastMetadata(recvState.getSourceId()); if (metaData == null) { Log.e(TAG, "Fail to find broadcast source, sourceId = " + recvState.getSourceId()); Loading Loading @@ -1350,7 +1393,7 @@ public class BassClientStateMachine extends StateMachine { + messageWhatToString(getCurrentMessage().what)); removeDeferredMessages(CONNECT); if (mLastConnectionState == BluetoothProfile.STATE_CONNECTED) { log("CONNECTED->CONNTECTED: Ignore"); log("CONNECTED->CONNECTED: Ignore"); } else { broadcastConnectionState(mDevice, mLastConnectionState, BluetoothProfile.STATE_CONNECTED); Loading Loading @@ -1747,9 +1790,17 @@ public class BassClientStateMachine extends StateMachine { log("broadcastConnectionState " + device + ": " + fromState + "->" + toState); if (fromState == BluetoothProfile.STATE_CONNECTED && toState == BluetoothProfile.STATE_CONNECTED) { log("CONNECTED->CONNTECTED: Ignore"); log("CONNECTED->CONNECTED: Ignore"); return; } Intent intent = new Intent(BluetoothLeBroadcastAssistant.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, fromState); intent.putExtra(BluetoothProfile.EXTRA_STATE, toState); 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, Utils.getTempAllowlistBroadcastOptions()); } int getConnectionState() { Loading Loading
android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -95,7 +95,8 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { } void OnDeviceAvailable(const RawAddress& bd_addr, int group_id, int group_size, const bluetooth::Uuid& uuid) override { int group_size, int rank, const bluetooth::Uuid& uuid) override { std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; Loading @@ -111,7 +112,7 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDeviceAvailable, addr.get(), (jint)group_id, (jint)group_size, UUID_PARAMS(uuid)); (jint)rank, UUID_PARAMS(uuid)); } void OnSetMemberAvailable(const RawAddress& bd_addr, int group_id) override { Loading Loading @@ -156,7 +157,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) { env->GetMethodID(clazz, "onConnectionStateChanged", "([BI)V"); method_onDeviceAvailable = env->GetMethodID(clazz, "onDeviceAvailable", "([BIIJJ)V"); env->GetMethodID(clazz, "onDeviceAvailable", "([BIIIJJ)V"); method_onSetMemberAvailable = env->GetMethodID(clazz, "onSetMemberAvailable", "([BI)V"); Loading
android/app/jni/com_android_bluetooth_gatt.cpp +27 −14 Original line number Diff line number Diff line Loading @@ -16,17 +16,18 @@ #define LOG_TAG "BtGatt.JNI" #include "com_android_bluetooth.h" #include "hardware/bt_gatt.h" #include "utils/Log.h" #include <base/bind.h> #include <base/callback.h> #include <cutils/log.h> #include <string.h> #include <array> #include <memory> #include <shared_mutex> #include <cutils/log.h> #include "com_android_bluetooth.h" #include "hardware/bt_gatt.h" #include "utils/Log.h" #define info(fmt, ...) ALOGI("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) #define debug(fmt, ...) \ ALOGD("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) Loading Loading @@ -191,6 +192,7 @@ static const btgatt_interface_t* sGattIf = NULL; static jobject mCallbacksObj = NULL; static jobject mAdvertiseCallbacksObj = NULL; static jobject mPeriodicScanCallbacksObj = NULL; static std::shared_mutex callbacks_mutex; /** * BTA client callbacks Loading Loading @@ -802,8 +804,9 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnAdvertisingSetStarted(int reg_id, uint8_t advertiser_id, int8_t tx_power, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingSetStarted, reg_id, advertiser_id, tx_power, status); Loading @@ -811,24 +814,27 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingEnabled, advertiser_id, enable, status); } void OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingDataSet, advertiser_id, status); } void OnScanResponseDataSet(uint8_t advertiser_id, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onScanResponseDataSet, advertiser_id, status); Loading @@ -836,8 +842,9 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t tx_power, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onAdvertisingParametersUpdated, advertiser_id, tx_power, status); Loading @@ -845,16 +852,18 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onPeriodicAdvertisingParametersUpdated, advertiser_id, status); } void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onPeriodicAdvertisingDataSet, advertiser_id, status); Loading @@ -862,8 +871,9 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onPeriodicAdvertisingEnabled, advertiser_id, enable, status); Loading @@ -871,8 +881,9 @@ class JniAdvertisingCallbacks : AdvertisingCallbacks { void OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type, RawAddress address) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbackEnv.valid() || mAdvertiseCallbacksObj == NULL) return; ScopedLocalRef<jstring> addr(sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &address)); Loading Loading @@ -1998,6 +2009,7 @@ static void advertiseClassInitNative(JNIEnv* env, jclass clazz) { } static void advertiseInitializeNative(JNIEnv* env, jobject object) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); if (mAdvertiseCallbacksObj != NULL) { ALOGW("Cleaning up Advertise callback object"); env->DeleteGlobalRef(mAdvertiseCallbacksObj); Loading @@ -2008,6 +2020,7 @@ static void advertiseInitializeNative(JNIEnv* env, jobject object) { } static void advertiseCleanupNative(JNIEnv* env, jobject object) { std::shared_lock<std::shared_mutex> lock(callbacks_mutex); if (mAdvertiseCallbacksObj != NULL) { env->DeleteGlobalRef(mAdvertiseCallbacksObj); mAdvertiseCallbacksObj = NULL; Loading
android/app/src/com/android/bluetooth/a2dp/A2dpService.java +0 −8 Original line number Diff line number Diff line Loading @@ -1471,10 +1471,6 @@ public class A2dpService extends ProfileService { A2dpService service = getService(source); BluetoothCodecStatus codecStatus = null; if (service != null) { if (checkCallerTargetSdk(mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) { enforceBluetoothPrivilegedPermission(service); } codecStatus = service.getCodecStatus(device); } receiver.send(codecStatus); Loading @@ -1490,10 +1486,6 @@ public class A2dpService extends ProfileService { if (service == null) { return; } if (checkCallerTargetSdk(mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) { enforceBluetoothPrivilegedPermission(service); } service.setCodecConfigPreference(device, codecConfig); } Loading
android/app/src/com/android/bluetooth/bass_client/BassClientService.java +6 −24 Original line number Diff line number Diff line Loading @@ -83,7 +83,6 @@ public class BassClientService extends ProfileService { private Map<BluetoothDevice, Integer> mDeviceToSyncHandleMap; /*syncHandle, parsed BaseData data*/ private Map<Integer, BaseData> mSyncHandleToBaseDataMap; private Map<Integer, BluetoothLeBroadcastMetadata> mBroadcastSources; /*bcastSrcDevice, corresponding PeriodicAdvertisementResult*/ private Map<BluetoothDevice, PeriodicAdvertisementResult> mPeriodicAdvertisementResultMap; private ScanCallback mSearchScanCallback; Loading Loading @@ -181,25 +180,6 @@ public class BassClientService extends ProfileService { return base; } void updateSourceInternal(int sourceId, BluetoothLeBroadcastMetadata metaData) { if (mBroadcastSources == null) { return; } if (metaData != null) { // This will replace old metadata with new one mBroadcastSources.put(sourceId, metaData); } else { mBroadcastSources.remove(sourceId); } } BluetoothLeBroadcastMetadata getSourceInternal(int sourceId) { if (mBroadcastSources != null) { return mBroadcastSources.get(sourceId); } return null; } void setActiveSyncedSource(BluetoothDevice scanDelegator, BluetoothDevice sourceDevice) { log("setActiveSyncedSource: scanDelegator" + scanDelegator + ":: sourceDevice:" + sourceDevice); Loading Loading @@ -283,10 +263,6 @@ public class BassClientService extends ProfileService { mActiveSourceMap.clear(); mActiveSourceMap = null; } if (mBroadcastSources != null) { mBroadcastSources.clear(); mBroadcastSources = null; } if (mBassUtils != null) { mBassUtils.cleanUp(); mBassUtils = null; Loading Loading @@ -765,6 +741,9 @@ public class BassClientService extends ProfileService { BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR); return; } if (stateMachine.hasPendingSourceOperation()) { throw new IllegalStateException("addSource: source operation already pending"); } if (!hasRoomForBroadcastSourceAddition(sink)) { log("addSource: device has no room"); mCallbacks.notifySourceAddFailed(sink, sourceMetadata, Loading Loading @@ -808,6 +787,9 @@ public class BassClientService extends ProfileService { BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR); return; } if (stateMachine.hasPendingSourceOperation()) { throw new IllegalStateException("modifySource: source operation already pending"); } Message message = stateMachine.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE); message.arg1 = sourceId; message.obj = updatedMetadata; Loading
android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +59 −8 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ */ package com.android.bluetooth.bass_client; import static android.Manifest.permission.BLUETOOTH_CONNECT; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; Loading @@ -65,6 +67,7 @@ import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothLeAudioCodecConfigMetadata; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastAssistant; import android.bluetooth.BluetoothLeBroadcastChannel; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; Loading @@ -76,6 +79,7 @@ import android.bluetooth.le.PeriodicAdvertisingManager; import android.bluetooth.le.PeriodicAdvertisingReport; import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; import android.content.Intent; import android.os.Binder; import android.os.Looper; import android.os.Message; Loading @@ -83,6 +87,7 @@ import android.os.ParcelUuid; import android.provider.DeviceConfig; import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -136,6 +141,7 @@ public class BassClientStateMachine extends StateMachine { private final Map<Integer, BluetoothLeBroadcastReceiveState> mBluetoothLeBroadcastReceiveStates = new HashMap<Integer, BluetoothLeBroadcastReceiveState>(); private final Map<Integer, BluetoothLeBroadcastMetadata> mCurrentMetadata = new HashMap(); private final Disconnected mDisconnected = new Disconnected(); private final Connected mConnected = new Connected(); private final Connecting mConnecting = new Connecting(); Loading Loading @@ -236,6 +242,24 @@ public class BassClientStateMachine extends StateMachine { mPendingOperation = -1; mPendingSourceId = -1; mPendingMetadata = null; mCurrentMetadata.clear(); } Boolean hasPendingSourceOperation() { return mPendingMetadata != null; } BluetoothLeBroadcastMetadata getCurrentBroadcastMetadata(Integer sourceId) { return mCurrentMetadata.getOrDefault(sourceId, null); } private void setCurrentBroadcastMetadata(Integer sourceId, BluetoothLeBroadcastMetadata metadata) { if (metadata != null) { mCurrentMetadata.put(sourceId, metadata); } else { mCurrentMetadata.remove(sourceId); } } BluetoothLeBroadcastReceiveState getBroadcastReceiveStateForSourceDevice( Loading Loading @@ -724,7 +748,7 @@ public class BassClientStateMachine extends StateMachine { mService.getCallbacks().notifySourceAdded(mDevice, recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); if (mPendingMetadata != null) { mService.updateSourceInternal(recvState.getSourceId(), mPendingMetadata); setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata); } checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); Loading @@ -734,13 +758,13 @@ public class BassClientStateMachine extends StateMachine { BluetoothDevice removedDevice = oldRecvState.getSourceDevice(); log("sourceInfo removal" + removedDevice); cancelActiveSync(removedDevice); mService.updateSourceInternal(oldRecvState.getSourceId(), null); setCurrentBroadcastMetadata(oldRecvState.getSourceId(), null); mService.getCallbacks().notifySourceRemoved(mDevice, oldRecvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); } else { log("update to an existing recvState"); mService.updateSourceInternal(recvState.getSourceId(), mPendingMetadata); setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata); mService.getCallbacks().notifySourceModified(mDevice, recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); checkAndUpdateBroadcastCode(recvState); Loading Loading @@ -959,6 +983,7 @@ public class BassClientStateMachine extends StateMachine { } mPendingOperation = -1; mPendingMetadata = null; mCurrentMetadata.clear(); } @VisibleForTesting Loading @@ -975,6 +1000,16 @@ public class BassClientStateMachine extends StateMachine { } else { broadcastConnectionState( mDevice, mLastConnectionState, BluetoothProfile.STATE_DISCONNECTED); if (mLastConnectionState != BluetoothProfile.STATE_DISCONNECTED) { // Reconnect in background if not disallowed by the service if (mService.okToConnect(mDevice)) { mBluetoothGatt = mDevice.connectGatt(mService, true, mGattCallback, BluetoothDevice.TRANSPORT_LE, (BluetoothDevice.PHY_LE_1M_MASK | BluetoothDevice.PHY_LE_2M_MASK | BluetoothDevice.PHY_LE_CODED_MASK), null); } } } } Loading Loading @@ -1011,7 +1046,15 @@ public class BassClientStateMachine extends StateMachine { } break; case DISCONNECT: Log.w(TAG, "Disconnected: DISCONNECT ignored: " + mDevice); // Disconnect if there's an ongoing background connection if (mBluetoothGatt != null) { log("Cancelling the background connection to " + mDevice); mBluetoothGatt.disconnect(); mBluetoothGatt.close(); mBluetoothGatt = null; } else { Log.d(TAG, "Disconnected: DISCONNECT ignored: " + mDevice); } break; case CONNECTION_STATE_CHANGED: int state = (int) message.obj; Loading Loading @@ -1289,8 +1332,8 @@ public class BassClientStateMachine extends StateMachine { res[1] = (byte) recvState.getSourceId(); log("convertRecvStateToSetBroadcastCodeByteArray: Source device : " + recvState.getSourceDevice()); BluetoothLeBroadcastMetadata metaData = mService.getSourceInternal( recvState.getSourceId()); BluetoothLeBroadcastMetadata metaData = getCurrentBroadcastMetadata(recvState.getSourceId()); if (metaData == null) { Log.e(TAG, "Fail to find broadcast source, sourceId = " + recvState.getSourceId()); Loading Loading @@ -1350,7 +1393,7 @@ public class BassClientStateMachine extends StateMachine { + messageWhatToString(getCurrentMessage().what)); removeDeferredMessages(CONNECT); if (mLastConnectionState == BluetoothProfile.STATE_CONNECTED) { log("CONNECTED->CONNTECTED: Ignore"); log("CONNECTED->CONNECTED: Ignore"); } else { broadcastConnectionState(mDevice, mLastConnectionState, BluetoothProfile.STATE_CONNECTED); Loading Loading @@ -1747,9 +1790,17 @@ public class BassClientStateMachine extends StateMachine { log("broadcastConnectionState " + device + ": " + fromState + "->" + toState); if (fromState == BluetoothProfile.STATE_CONNECTED && toState == BluetoothProfile.STATE_CONNECTED) { log("CONNECTED->CONNTECTED: Ignore"); log("CONNECTED->CONNECTED: Ignore"); return; } Intent intent = new Intent(BluetoothLeBroadcastAssistant.ACTION_CONNECTION_STATE_CHANGED); intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, fromState); intent.putExtra(BluetoothProfile.EXTRA_STATE, toState); 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, Utils.getTempAllowlistBroadcastOptions()); } int getConnectionState() { Loading