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

Commit b705f29f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "BluetoothLeAudio: Improve handling lead device disconnection" into...

Merge "BluetoothLeAudio: Improve handling lead device disconnection" into tm-dev am: 38d7e669 am: 8581ba84 am: fe0b66f1

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



Change-Id: I64f8a94e8c5ad97b2eaecf0dcfb12bd99f53878f
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 7604e7a2 fe0b66f1
Loading
Loading
Loading
Loading
+62 −5
Original line number Original line Diff line number Diff line
@@ -136,12 +136,15 @@ public class LeAudioService extends ProfileService {
            mIsActive = false;
            mIsActive = false;
            mActiveContexts = ACTIVE_CONTEXTS_NONE;
            mActiveContexts = ACTIVE_CONTEXTS_NONE;
            mCodecStatus = null;
            mCodecStatus = null;
            mLostDevicesWhileStreaming = new ArrayList<>();
        }
        }


        public Boolean mIsConnected;
        public Boolean mIsConnected;
        public Boolean mIsActive;
        public Boolean mIsActive;
        public Integer mActiveContexts;
        public Integer mActiveContexts;
        public BluetoothLeAudioCodecStatus mCodecStatus;
        public BluetoothLeAudioCodecStatus mCodecStatus;
        /* This can be non empty only for the streaming time */
        List<BluetoothDevice> mLostDevicesWhileStreaming;
    }
    }


    List<BluetoothLeAudioCodecConfig> mInputLocalCodecCapabilities = new ArrayList<>();
    List<BluetoothLeAudioCodecConfig> mInputLocalCodecCapabilities = new ArrayList<>();
@@ -1035,6 +1038,21 @@ public class LeAudioService extends ProfileService {
        return BluetoothProfileConnectionInfo.CREATOR.createFromParcel(parcel);
        return BluetoothProfileConnectionInfo.CREATOR.createFromParcel(parcel);
    }
    }


    private void clearLostDevicesWhileStreaming(LeAudioGroupDescriptor descriptor) {
        for (BluetoothDevice dev : descriptor.mLostDevicesWhileStreaming) {
            LeAudioStateMachine sm = mStateMachines.get(dev);
            if (sm == null) {
                continue;
            }

            LeAudioStackEvent stackEvent =
                new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
            stackEvent.device = dev;
            stackEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED;
            sm.sendMessage(LeAudioStateMachine.STACK_EVENT, stackEvent);
        }
    }

    // Suppressed since this is part of a local process
    // Suppressed since this is part of a local process
    @SuppressLint("AndroidFrameworkRequiresPermission")
    @SuppressLint("AndroidFrameworkRequiresPermission")
    void messageFromNative(LeAudioStackEvent stackEvent) {
    void messageFromNative(LeAudioStackEvent stackEvent) {
@@ -1046,7 +1064,41 @@ public class LeAudioService extends ProfileService {
        // Some events require device state machine
        // Some events require device state machine
            synchronized (mStateMachines) {
            synchronized (mStateMachines) {
                LeAudioStateMachine sm = mStateMachines.get(device);
                LeAudioStateMachine sm = mStateMachines.get(device);
                if (sm == null) {
                if (sm != null) {
                    /*
                    * To improve scenario when lead Le Audio device is disconnected for the
                    * streaming group, while there are still other devices streaming,
                    * LeAudioService will not notify audio framework or other users about
                    * Le Audio lead device disconnection. Instead we try to reconnect under the hood
                    * and keep using lead device as a audio device indetifier in the audio framework
                    * in order to not stop the stream.
                    */
                    int groupId = getGroupId(device);
                    synchronized (mGroupLock) {
                        LeAudioGroupDescriptor descriptor = mGroupDescriptors.get(groupId);
                        switch (stackEvent.valueInt1) {
                            case LeAudioStackEvent.CONNECTION_STATE_DISCONNECTING:
                            case LeAudioStackEvent.CONNECTION_STATE_DISCONNECTED:
                                if (descriptor != null && (Objects.equals(device,
                                        mActiveAudioOutDevice)
                                        || Objects.equals(device, mActiveAudioInDevice))
                                        && (getConnectedPeerDevices(groupId).size() > 1)) {
                                    descriptor.mLostDevicesWhileStreaming.add(device);
                                    return;
                                }
                                break;
                            case LeAudioStackEvent.CONNECTION_STATE_CONNECTED:
                            case LeAudioStackEvent.CONNECTION_STATE_CONNECTING:
                                if (descriptor != null) {
                                    descriptor.mLostDevicesWhileStreaming.remove(device);
                                    /* Try to connect other devices from the group */
                                    connectSet(device);
                                }
                                break;
                        }
                    }
                } else {
                    /* state machine does not exist yet */
                    switch (stackEvent.valueInt1) {
                    switch (stackEvent.valueInt1) {
                        case LeAudioStackEvent.CONNECTION_STATE_CONNECTED:
                        case LeAudioStackEvent.CONNECTION_STATE_CONNECTED:
                        case LeAudioStackEvent.CONNECTION_STATE_CONNECTING:
                        case LeAudioStackEvent.CONNECTION_STATE_CONNECTING:
@@ -1057,12 +1109,12 @@ public class LeAudioService extends ProfileService {
                        default:
                        default:
                            break;
                            break;
                    }
                    }
                }


                    if (sm == null) {
                    if (sm == null) {
                        Log.e(TAG, "Cannot process stack event: no state machine: " + stackEvent);
                        Log.e(TAG, "Cannot process stack event: no state machine: " + stackEvent);
                        return;
                        return;
                    }
                    }
                }


                sm.sendMessage(LeAudioStateMachine.STACK_EVENT, stackEvent);
                sm.sendMessage(LeAudioStateMachine.STACK_EVENT, stackEvent);
                return;
                return;
@@ -1174,6 +1226,8 @@ public class LeAudioService extends ProfileService {
                            updateActiveDevices(groupId, descriptor.mActiveContexts,
                            updateActiveDevices(groupId, descriptor.mActiveContexts,
                                    ACTIVE_CONTEXTS_NONE, descriptor.mIsActive);
                                    ACTIVE_CONTEXTS_NONE, descriptor.mIsActive);
                            notifyGroupStatus = true;
                            notifyGroupStatus = true;
                            /* Clear lost devices */
                            clearLostDevicesWhileStreaming(descriptor);
                        }
                        }
                    } else {
                    } else {
                        Log.e(TAG, "no descriptors for group: " + groupId);
                        Log.e(TAG, "no descriptors for group: " + groupId);
@@ -2417,6 +2471,9 @@ public class LeAudioService extends ProfileService {
            ProfileService.println(sb, "    mActiveContexts: " + descriptor.mActiveContexts);
            ProfileService.println(sb, "    mActiveContexts: " + descriptor.mActiveContexts);
            ProfileService.println(sb, "    group lead: " + getConnectedGroupLeadDevice(groupId));
            ProfileService.println(sb, "    group lead: " + getConnectedGroupLeadDevice(groupId));
            ProfileService.println(sb, "    first device: " + getFirstDeviceFromGroup(groupId));
            ProfileService.println(sb, "    first device: " + getFirstDeviceFromGroup(groupId));
            for (BluetoothDevice dev : descriptor.mLostDevicesWhileStreaming) {
                ProfileService.println(sb, "        lost device: " + dev);
            }
        }
        }
    }
    }
}
}
+3 −1
Original line number Original line Diff line number Diff line
@@ -803,7 +803,9 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
     * of the system, which wants to set to active a particular Le Audio group.
     * of the system, which wants to set to active a particular Le Audio group.
     *
     *
     * Note: getActiveDevice() returns the Lead device for the currently active LE Audio group.
     * Note: getActiveDevice() returns the Lead device for the currently active LE Audio group.
     * Note: When lead device gets disconnected, there will be new lead device for the group.
     * Note: When Lead device gets disconnected while Le Audio group is active and has more devices
     * in the group, then Lead device will not change. If Lead device gets disconnected, for the
     * Le Audio group which is not active, a new Lead device will be chosen
     *
     *
     * @param groupId The group id.
     * @param groupId The group id.
     * @return group lead device.
     * @return group lead device.