Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61f87e3e authored by Jack He's avatar Jack He Committed by Automerger Merge Worker
Browse files

Merge changes I64de4bb5,I765f4a82,I2f2054c6,I5fdc54d0,I5dc62758, ... into...

Merge changes I64de4bb5,I765f4a82,I2f2054c6,I5fdc54d0,I5dc62758, ... into tm-dev am: 274267cd am: 50f2aa87

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/18351767



Change-Id: I7b56cff1448863aa62a2322c8c02bf64c6a1a352
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 51febf83 50f2aa87
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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 {
@@ -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");
+6 −24
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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;
@@ -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,
@@ -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;
+59 −8
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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();
@@ -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(
@@ -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);
@@ -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);
@@ -959,6 +983,7 @@ public class BassClientStateMachine extends StateMachine {
        }
        mPendingOperation = -1;
        mPendingMetadata = null;
        mCurrentMetadata.clear();
    }

    @VisibleForTesting
@@ -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);
                    }
                }
            }
        }

@@ -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;
@@ -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());
@@ -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);
@@ -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() {
+2 −1
Original line number Diff line number Diff line
@@ -149,13 +149,14 @@ public class CsipSetCoordinatorNativeInterface {
    /** Device availability */
    @VisibleForTesting
    public void onDeviceAvailable(
            byte[] address, int groupId, int groupSize, long uuidLsb, long uuidMsb) {
            byte[] address, int groupId, int groupSize, int rank, long uuidLsb, long uuidMsb) {
        UUID uuid = new UUID(uuidMsb, uuidLsb);
        CsipSetCoordinatorStackEvent event = new CsipSetCoordinatorStackEvent(
                CsipSetCoordinatorStackEvent.EVENT_TYPE_DEVICE_AVAILABLE);
        event.device = getDevice(address);
        event.valueInt1 = groupId;
        event.valueInt2 = groupSize;
        event.valueInt3 = rank;
        event.valueUuid1 = uuid;

        if (DBG) {
+47 −13
Original line number Diff line number Diff line
@@ -52,11 +52,9 @@ import com.android.modules.utils.SynchronousResultReceiver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@@ -87,7 +85,8 @@ public class CsipSetCoordinatorService extends ProfileService {
            new HashMap<>();

    private final Map<Integer, ParcelUuid> mGroupIdToUuidMap = new HashMap<>();
    private final Map<BluetoothDevice, Set<Integer>> mDeviceGroupIdMap = new ConcurrentHashMap<>();
    private final Map<BluetoothDevice, Map<Integer, Integer>> mDeviceGroupIdRankMap =
            new ConcurrentHashMap<>();
    private final Map<Integer, Integer> mGroupIdToGroupSize = new HashMap<>();
    private final Map<ParcelUuid, Map<Executor, IBluetoothCsipSetCoordinatorCallback>> mCallbacks =
            new HashMap<>();
@@ -201,7 +200,7 @@ public class CsipSetCoordinatorService extends ProfileService {
            }
        }

        mDeviceGroupIdMap.clear();
        mDeviceGroupIdRankMap.clear();
        mCallbacks.clear();
        mGroupIdToGroupSize.clear();
        mGroupIdToUuidMap.clear();
@@ -554,6 +553,17 @@ public class CsipSetCoordinatorService extends ProfileService {
        }
    }

    /**
     * Check whether a given group is currently locked.
     * @param groupId unique group identifier
     * @return true if group is currently locked, otherwise false.
     *
     * @hide
     */
    public boolean isGroupLocked(int groupId) {
        return mLocks.containsKey(groupId);
    }

    /**
     * Get collection of group IDs for a given UUID
     * @param uuid
@@ -573,13 +583,37 @@ public class CsipSetCoordinatorService extends ProfileService {
     * @return map of group id and related uuids.
     */
    public Map<Integer, ParcelUuid> getGroupUuidMapByDevice(BluetoothDevice device) {
        Set<Integer> device_groups = mDeviceGroupIdMap.getOrDefault(device, new HashSet<>());
        Map<Integer, Integer> device_groups =
                mDeviceGroupIdRankMap.getOrDefault(device, new HashMap<>());
        return mGroupIdToUuidMap.entrySet()
                .stream()
                .filter(e -> device_groups.contains(e.getKey()))
                .filter(e -> device_groups.containsKey(e.getKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }

    /**
     * Get grouped devices
     * @param groupId group ID
     * @return related list of devices sorted from the lowest to the highest rank value.
     */
    public @NonNull List<BluetoothDevice> getGroupDevicesOrdered(int groupId) {
        final Map<BluetoothDevice, Integer> deviceRankMap = new HashMap();
        for (Map.Entry<BluetoothDevice, ?> entry : mDeviceGroupIdRankMap.entrySet()) {
            Map<Integer, Integer> rankMap = (Map<Integer, Integer>) entry.getValue();
            BluetoothDevice device = entry.getKey();
            if (rankMap.containsKey(groupId)) {
                deviceRankMap.put(device, rankMap.get(groupId));
            }
        }

        // Return device list sorted by descending rank order
        return deviceRankMap.entrySet()
                .stream()
                .sorted(Map.Entry.comparingByValue())
                .map(e -> e.getKey())
                .collect(Collectors.toList());
    }

    /**
     * Get group desired size
     * @param groupId group ID
@@ -590,18 +624,18 @@ public class CsipSetCoordinatorService extends ProfileService {
                IBluetoothCsipSetCoordinator.CSIS_GROUP_SIZE_UNKNOWN);
    }

    private void handleDeviceAvailable(BluetoothDevice device, int groupId, UUID uuid) {
    private void handleDeviceAvailable(BluetoothDevice device, int groupId, int rank, UUID uuid) {
        ParcelUuid parcel_uuid = new ParcelUuid(uuid);
        if (!getAllGroupIds(parcel_uuid).contains(groupId)) {
            mGroupIdToUuidMap.put(groupId, parcel_uuid);
        }

        if (!mDeviceGroupIdMap.containsKey(device)) {
            mDeviceGroupIdMap.put(device, new HashSet<Integer>());
        if (!mDeviceGroupIdRankMap.containsKey(device)) {
            mDeviceGroupIdRankMap.put(device, new HashMap<Integer, Integer>());
        }

        Set<Integer> all_device_groups = mDeviceGroupIdMap.get(device);
        all_device_groups.add(groupId);
        Map<Integer, Integer> all_device_groups = mDeviceGroupIdRankMap.get(device);
        all_device_groups.put(groupId, rank);
    }

    private void executeCallback(Executor exec, IBluetoothCsipSetCoordinatorCallback callback,
@@ -700,7 +734,7 @@ public class CsipSetCoordinatorService extends ProfileService {
            intent.putExtra(
                    BluetoothCsipSetCoordinator.EXTRA_CSIS_GROUP_TYPE_UUID, stackEvent.valueUuid1);

            handleDeviceAvailable(device, groupId, stackEvent.valueUuid1);
            handleDeviceAvailable(device, groupId, stackEvent.valueInt3, stackEvent.valueUuid1);
        } else if (stackEvent.type
                == CsipSetCoordinatorStackEvent.EVENT_TYPE_SET_MEMBER_AVAILABLE) {
            Objects.requireNonNull(device, "Device should never be null, event: " + stackEvent);
@@ -808,7 +842,7 @@ public class CsipSetCoordinatorService extends ProfileService {
            return;
        }

        mDeviceGroupIdMap.remove(device);
        mDeviceGroupIdRankMap.remove(device);

        synchronized (mStateMachines) {
            CsipSetCoordinatorStateMachine sm = mStateMachines.get(device);
Loading