Update CSIP base uuid devie set into a single device detail preference

Bug: 178981521
Bug: 150670922
Test: pair with two device which are a coordinated set, and make sure
the UI only show one device

Merged-In: I1a8d570da1af7fa4c8b3a99f8ce69d23b574e96c
Change-Id: I1a8d570da1af7fa4c8b3a99f8ce69d23b574e96c
This commit is contained in:
Alice Kuo
2021-03-05 14:45:54 +08:00
parent e731e209d3
commit c32061b88e
7 changed files with 471 additions and 20 deletions

View File

@@ -18,6 +18,7 @@ package com.android.settingslib.bluetooth;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
@@ -351,8 +352,10 @@ public class BluetoothEventManager {
cachedDevice.onBondingStateChanged(bondState);
if (bondState == BluetoothDevice.BOND_NONE) {
/* Check if we need to remove other Hearing Aid devices */
if (cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
// Check if we need to remove other Coordinated set member devices / Hearing Aid
// devices
if (cachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
|| cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
mDeviceManager.onDeviceUnpaired(cachedDevice);
}
int reason = intent.getIntExtra(BluetoothDevice.EXTRA_REASON,

View File

@@ -18,6 +18,7 @@ package com.android.settingslib.bluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
@@ -41,7 +42,9 @@ import com.android.settingslib.Utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -66,6 +69,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
private final Object mProfileLock = new Object();
BluetoothDevice mDevice;
private long mHiSyncId;
private int mGroupId;
// Need this since there is no method for getting RSSI
short mRssi;
// mProfiles and mRemovedProfiles does not do swap() between main and sub device. It is
@@ -100,6 +104,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
private boolean mIsA2dpProfileConnectedFail = false;
private boolean mIsHeadsetProfileConnectedFail = false;
private boolean mIsHearingAidProfileConnectedFail = false;
// Group member devices for the coordinated set
private Set<CachedBluetoothDevice> mMemberDevices = new HashSet<CachedBluetoothDevice>();
// Group second device for Hearing Aid
private CachedBluetoothDevice mSubDevice;
@@ -133,6 +139,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
mDevice = device;
fillData();
mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID;
mGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
}
/**
@@ -317,6 +324,24 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
return mIsCoordinatedSetMember;
}
/**
* Get the coordinated set group id.
*
* @return the group id.
*/
public int getGroupId() {
return mGroupId;
}
/**
* Set the coordinated set group id.
*
* @param id the group id from the CSIP.
*/
public void setGroupId(int id) {
mGroupId = id;
}
void onBondingDockConnect() {
// Attempt to connect if UUIDs are available. Otherwise,
// we will connect when the ACTION_UUID intent arrives.
@@ -1191,4 +1216,52 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
mSubDevice.mJustDiscovered = tmpJustDiscovered;
fetchActiveDevices();
}
/**
* @return a set of member devices that are in the same coordinated set with this device.
*/
public Set<CachedBluetoothDevice> getMemberDevice() {
return mMemberDevices;
}
/**
* Store the member devices that are in the same coordinated set.
*/
public void setMemberDevice(CachedBluetoothDevice memberDevice) {
mMemberDevices.add(memberDevice);
}
/**
* Remove a device from the member device sets.
*/
public void removeMemberDevice(CachedBluetoothDevice memberDevice) {
mMemberDevices.remove(memberDevice);
}
/**
* In order to show the preference for the whole group, we always set the main device as the
* first connected device in the coordinated set, and then switch the content of the main
* device and member devices.
*
* @param prevMainDevice the previous Main device, it will be added into the member device set.
* @param newMainDevie the new Main device, it will be removed from the member device set.
*/
public void switchMemberDeviceContent(CachedBluetoothDevice prevMainDevice,
CachedBluetoothDevice newMainDevie) {
// Backup from main device
final BluetoothDevice tmpDevice = mDevice;
final short tmpRssi = mRssi;
final boolean tmpJustDiscovered = mJustDiscovered;
// Set main device from sub device
mDevice = newMainDevie.mDevice;
mRssi = newMainDevie.mRssi;
mJustDiscovered = newMainDevie.mJustDiscovered;
setMemberDevice(prevMainDevice);
mMemberDevices.remove(newMainDevie);
// Set sub device from backup
newMainDevie.mDevice = tmpDevice;
newMainDevie.mRssi = tmpRssi;
newMainDevie.mJustDiscovered = tmpJustDiscovered;
fetchActiveDevices();
}
}

View File

@@ -18,6 +18,7 @@ package com.android.settingslib.bluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.util.Log;
@@ -26,6 +27,7 @@ import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* CachedBluetoothDeviceManager manages the set of remote Bluetooth devices.
@@ -41,11 +43,14 @@ public class CachedBluetoothDeviceManager {
final List<CachedBluetoothDevice> mCachedDevices = new ArrayList<CachedBluetoothDevice>();
@VisibleForTesting
HearingAidDeviceManager mHearingAidDeviceManager;
@VisibleForTesting
CsipDeviceManager mCsipDeviceManager;
CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
mContext = context;
mBtManager = localBtManager;
mHearingAidDeviceManager = new HearingAidDeviceManager(localBtManager, mCachedDevices);
mCsipDeviceManager = new CsipDeviceManager(localBtManager, mCachedDevices);
}
public synchronized Collection<CachedBluetoothDevice> getCachedDevicesCopy() {
@@ -79,7 +84,16 @@ public class CachedBluetoothDeviceManager {
if (cachedDevice.getDevice().equals(device)) {
return cachedDevice;
}
// Check sub devices if it exists
// Check the member devices for the coordinated set if it exists
final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
if (memberDevices != null) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
if (memberDevice.getDevice().equals(device)) {
return memberDevice;
}
}
}
// Check sub devices for hearing aid if it exists
CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
if (subDevice != null && subDevice.getDevice().equals(device)) {
return subDevice;
@@ -102,8 +116,10 @@ public class CachedBluetoothDeviceManager {
newDevice = findDevice(device);
if (newDevice == null) {
newDevice = new CachedBluetoothDevice(mContext, profileManager, device);
mCsipDeviceManager.initCsipDeviceIfNeeded(newDevice);
mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(newDevice);
if (!mHearingAidDeviceManager.setSubDeviceIfNeeded(newDevice)) {
if (!mCsipDeviceManager.setMemberDeviceIfNeeded(newDevice)
&& !mHearingAidDeviceManager.setSubDeviceIfNeeded(newDevice)) {
mCachedDevices.add(newDevice);
mBtManager.getEventManager().dispatchDeviceAdded(newDevice);
}
@@ -114,13 +130,23 @@ public class CachedBluetoothDeviceManager {
}
/**
* Returns device summary of the pair of the hearing aid passed as the parameter.
* Returns device summary of the pair of the hearing aid / CSIP passed as the parameter.
*
* @param CachedBluetoothDevice device
* @return Device summary, or if the pair does not exist or if it is not a hearing aid,
* then {@code null}.
* @return Device summary, or if the pair does not exist or if it is not a hearing aid or
* a CSIP set member, then {@code null}.
*/
public synchronized String getSubDeviceSummary(CachedBluetoothDevice device) {
final Set<CachedBluetoothDevice> memberDevices = device.getMemberDevice();
if (memberDevices != null) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
if (!memberDevice.isConnected()) {
return null;
}
}
return device.getConnectionSummary();
}
CachedBluetoothDevice subDevice = device.getSubDevice();
if (subDevice != null && subDevice.isConnected()) {
return subDevice.getConnectionSummary();
@@ -132,12 +158,22 @@ public class CachedBluetoothDeviceManager {
* Search for existing sub device {@link CachedBluetoothDevice}.
*
* @param device the address of the Bluetooth device
* @return true for found sub device or false.
* @return true for found sub / member device or false.
*/
public synchronized boolean isSubDevice(BluetoothDevice device) {
for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
if (!cachedDevice.getDevice().equals(device)) {
// Check sub devices if it exists
// Check the member devices of the coordinated set if it exists
Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
if (memberDevices != null) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
if (memberDevice.getDevice().equals(device)) {
return true;
}
}
continue;
}
// Check sub devices of hearing aid if it exists
CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
if (subDevice != null && subDevice.getDevice().equals(device)) {
return true;
@@ -156,6 +192,14 @@ public class CachedBluetoothDeviceManager {
mHearingAidDeviceManager.updateHearingAidsDevices();
}
/**
* Updates the Csip devices; specifically the GroupId's. This routine is called when the
* CSIS is connected and the GroupId's are now available.
*/
public synchronized void updateCsipDevices() {
mCsipDeviceManager.updateCsipDevices();
}
/**
* Attempts to get the name of a remote device, otherwise returns the address.
*
@@ -185,6 +229,16 @@ public class CachedBluetoothDeviceManager {
private void clearNonBondedSubDevices() {
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
if (memberDevices != null) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
// Member device exists and it is not bonded
if (memberDevice.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
cachedDevice.removeMemberDevice(memberDevice);
}
}
return;
}
CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
if (subDevice != null
&& subDevice.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
@@ -201,6 +255,13 @@ public class CachedBluetoothDeviceManager {
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
cachedDevice.setJustDiscovered(false);
final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
if (memberDevices != null) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
memberDevice.setJustDiscovered(false);
}
return;
}
final CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
if (subDevice != null) {
subDevice.setJustDiscovered(false);
@@ -214,10 +275,19 @@ public class CachedBluetoothDeviceManager {
if (bluetoothState == BluetoothAdapter.STATE_TURNING_OFF) {
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
if (subDevice != null) {
if (subDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
cachedDevice.setSubDevice(null);
final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
if (memberDevices != null) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
if (memberDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
cachedDevice.removeMemberDevice(memberDevice);
}
}
} else {
CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
if (subDevice != null) {
if (subDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
cachedDevice.setSubDevice(null);
}
}
}
if (cachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
@@ -229,13 +299,32 @@ public class CachedBluetoothDeviceManager {
}
public synchronized boolean onProfileConnectionStateChangedIfProcessed(CachedBluetoothDevice
cachedDevice, int state) {
return mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice,
cachedDevice, int state, int profileId) {
if (profileId == BluetoothProfile.HEARING_AID) {
return mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice,
state);
}
if (profileId == BluetoothProfile.CSIP_SET_COORDINATOR) {
return mCsipDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice,
state);
}
return false;
}
public synchronized void onDeviceUnpaired(CachedBluetoothDevice device) {
CachedBluetoothDevice mainDevice = mHearingAidDeviceManager.findMainDevice(device);
CachedBluetoothDevice mainDevice = mCsipDeviceManager.findMainDevice(device);
final Set<CachedBluetoothDevice> memberDevices = device.getMemberDevice();
if (memberDevices != null) {
// Main device is unpaired, to unpair the member device
for (CachedBluetoothDevice memberDevice : memberDevices) {
memberDevice.unpair();
device.removeMemberDevice(memberDevice);
}
} else if (mainDevice != null) {
// the member device unpaired, to unpair main device
mainDevice.unpair();
}
mainDevice = mHearingAidDeviceManager.findMainDevice(device);
CachedBluetoothDevice subDevice = device.getSubDevice();
if (subDevice != null) {
// Main device is unpaired, to unpair sub device

View File

@@ -0,0 +1,247 @@
/*
* Copyright (C) 2021 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.
*/
package com.android.settingslib.bluetooth;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.os.ParcelUuid;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* CsipDeviceManager manages the set of remote CSIP Bluetooth devices.
*/
public class CsipDeviceManager {
private static final String TAG = "CsipDeviceManager";
private static final boolean DEBUG = BluetoothUtils.D;
private final LocalBluetoothManager mBtManager;
private final List<CachedBluetoothDevice> mCachedDevices;
CsipDeviceManager(LocalBluetoothManager localBtManager,
List<CachedBluetoothDevice> cachedDevices) {
mBtManager = localBtManager;
mCachedDevices = cachedDevices;
};
void initCsipDeviceIfNeeded(CachedBluetoothDevice newDevice) {
// Current it only supports the base uuid for CSIP and group this set in UI.
final int groupId = getBaseGroupId(newDevice.getDevice());
if (isValidGroupId(groupId)) {
log("initCsipDeviceIfNeeded: " + newDevice + " (group: " + groupId + ")");
// Once groupId is valid, assign groupId
newDevice.setGroupId(groupId);
}
}
private int getBaseGroupId(BluetoothDevice device) {
final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
final CsipSetCoordinatorProfile profileProxy = profileManager
.getCsipSetCoordinatorProfile();
if (profileProxy != null) {
final Map<Integer, ParcelUuid> groupIdMap = profileProxy
.getGroupUuidMapByDevice(device);
if (groupIdMap == null) {
return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
}
for (Map.Entry<Integer, ParcelUuid> entry: groupIdMap.entrySet()) {
if (entry.getValue().equals(BluetoothUuid.BASE_UUID)) {
return entry.getKey();
}
}
}
return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
}
boolean setMemberDeviceIfNeeded(CachedBluetoothDevice newDevice) {
final int groupId = newDevice.getGroupId();
if (isValidGroupId(groupId)) {
final CachedBluetoothDevice CsipDevice = getCachedDevice(groupId);
log("setMemberDeviceIfNeeded, main: " + CsipDevice + ", member: " + newDevice);
// Just add one of the coordinated set from a pair in the list that is shown in the UI.
// Once there is other devices with the same groupId, to add new device as member
// devices.
if (CsipDevice != null) {
CsipDevice.setMemberDevice(newDevice);
newDevice.setName(CsipDevice.getName());
return true;
}
}
return false;
}
private boolean isValidGroupId(int groupId) {
return groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
}
private CachedBluetoothDevice getCachedDevice(int groupId) {
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
if (cachedDevice.getGroupId() == groupId) {
return cachedDevice;
}
}
return null;
}
// To collect all set member devices and call #onGroupIdChanged to group device by GroupId
void updateCsipDevices() {
final Set<Integer> newGroupIdSet = new HashSet<Integer>();
for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
// Do nothing if GroupId has been assigned
if (!isValidGroupId(cachedDevice.getGroupId())) {
final int newGroupId = getBaseGroupId(cachedDevice.getDevice());
// Do nothing if there is no GroupId on Bluetooth device
if (isValidGroupId(newGroupId)) {
cachedDevice.setGroupId(newGroupId);
newGroupIdSet.add(newGroupId);
}
}
}
for (int groupId : newGroupIdSet) {
onGroupIdChanged(groupId);
}
}
// Group devices by groupId
@VisibleForTesting
void onGroupIdChanged(int groupId) {
int firstMatchedIndex = -1;
CachedBluetoothDevice mainDevice = null;
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
final CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
if (cachedDevice.getGroupId() != groupId) {
continue;
}
if (firstMatchedIndex == -1) {
// Found the first one
firstMatchedIndex = i;
mainDevice = cachedDevice;
continue;
}
log("onGroupIdChanged: removed from UI device =" + cachedDevice
+ ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex);
mainDevice.setMemberDevice(cachedDevice);
mCachedDevices.remove(i);
mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
break;
}
}
// @return {@code true}, the event is processed inside the method. It is for updating
// le audio device on group relationship when receiving connected or disconnected.
// @return {@code false}, it is not le audio device or to process it same as other profiles
boolean onProfileConnectionStateChangedIfProcessed(CachedBluetoothDevice cachedDevice,
int state) {
log("onProfileConnectionStateChangedIfProcessed: " + cachedDevice + ", state: " + state);
switch (state) {
case BluetoothProfile.STATE_CONNECTED:
onGroupIdChanged(cachedDevice.getGroupId());
CachedBluetoothDevice mainDevice = findMainDevice(cachedDevice);
if (mainDevice != null) {
if (mainDevice.isConnected()) {
// When main device exists and in connected state, receiving member device
// connection. To refresh main device UI
mainDevice.refresh();
return true;
} else {
// When both LE Audio devices are disconnected, receiving member device
// connection. To switch content and dispatch to notify UI change
mBtManager.getEventManager().dispatchDeviceRemoved(mainDevice);
mainDevice.switchMemberDeviceContent(mainDevice, cachedDevice);
mainDevice.refresh();
// It is necessary to do remove and add for updating the mapping on
// preference and device
mBtManager.getEventManager().dispatchDeviceAdded(mainDevice);
return true;
}
}
break;
case BluetoothProfile.STATE_DISCONNECTED:
mainDevice = findMainDevice(cachedDevice);
if (mainDevice != null) {
// When main device exists, receiving sub device disconnection
// To update main device UI
mainDevice.refresh();
return true;
}
final Set<CachedBluetoothDevice> memberSet = cachedDevice.getMemberDevice();
if (memberSet == null) {
break;
}
for (CachedBluetoothDevice device: memberSet) {
if (device.isConnected()) {
// Main device is disconnected and sub device is connected
// To copy data from sub device to main device
mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
cachedDevice.switchMemberDeviceContent(device, cachedDevice);
cachedDevice.refresh();
// It is necessary to do remove and add for updating the mapping on
// preference and device
mBtManager.getEventManager().dispatchDeviceAdded(cachedDevice);
return true;
}
}
break;
default:
// Do not handle this state.
}
return false;
}
CachedBluetoothDevice findMainDevice(CachedBluetoothDevice device) {
if (device == null || mCachedDevices == null) {
return null;
}
for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
if (isValidGroupId(cachedDevice.getGroupId())) {
Set<CachedBluetoothDevice> memberSet = cachedDevice.getMemberDevice();
if (memberSet == null) {
continue;
}
for (CachedBluetoothDevice memberDevice: memberSet) {
if (memberDevice != null && memberDevice.equals(device)) {
return cachedDevice;
}
}
}
}
return null;
}
private void log(String msg) {
if (DEBUG) {
Log.d(TAG, msg);
}
}
}

View File

@@ -26,6 +26,7 @@ import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.os.ParcelUuid;
import android.util.Log;
import androidx.annotation.RequiresApi;
@@ -34,6 +35,7 @@ import com.android.settingslib.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* CSIP Set Coordinator handles Bluetooth CSIP Set Coordinator role profile.
@@ -80,6 +82,7 @@ public class CsipSetCoordinatorProfile implements LocalBluetoothProfile {
device.refresh();
}
mDeviceManager.updateCsipDevices();
mProfileManager.callServiceConnectedListeners();
mIsProfileReady = true;
}
@@ -211,6 +214,18 @@ public class CsipSetCoordinatorProfile implements LocalBluetoothProfile {
return 0;
}
/**
* Get the device's groups and correspondsing uuids map.
* @param device the bluetooth device
* @return Map of groups ids and related UUIDs
*/
public Map<Integer, ParcelUuid> getGroupUuidMapByDevice(BluetoothDevice device) {
if (mService == null || device == null) {
return null;
}
return mService.getGroupUuidMapByDevice(device);
}
/**
* Return the profile name as a string.
*/

View File

@@ -318,11 +318,35 @@ public class LocalBluetoothProfileManager {
}
}
}
if (getCsipSetCoordinatorProfile() != null
&& mProfile instanceof CsipSetCoordinatorProfile
&& newState == BluetoothProfile.STATE_CONNECTED) {
// Check if the GroupID has being initialized
if (cachedDevice.getGroupId() == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
final Map<Integer, ParcelUuid> groupIdMap = getCsipSetCoordinatorProfile()
.getGroupUuidMapByDevice(cachedDevice.getDevice());
if (groupIdMap != null) {
for (Map.Entry<Integer, ParcelUuid> entry: groupIdMap.entrySet()) {
if (entry.getValue().equals(BluetoothUuid.BASE_UUID)) {
cachedDevice.setGroupId(entry.getKey());
break;
}
}
}
}
}
cachedDevice.onProfileStateChanged(mProfile, newState);
// Dispatch profile changed after device update
if (!(cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID
&& mDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice,
newState))) {
boolean needDispatchProfileConnectionState = true;
if (cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID
|| cachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
needDispatchProfileConnectionState = !mDeviceManager
.onProfileConnectionStateChangedIfProcessed(cachedDevice, newState,
mProfile.getProfileId());
}
if (needDispatchProfileConnectionState) {
cachedDevice.refresh();
mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
mProfile.getProfileId());

View File

@@ -206,7 +206,7 @@ public class LocalBluetoothProfileManagerTest {
mContext.sendBroadcast(mIntent);
verify(mDeviceManager).onProfileConnectionStateChangedIfProcessed(mCachedBluetoothDevice,
BluetoothProfile.STATE_CONNECTED);
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
}
/**