summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author SongFerng Wang <songferngwang@google.com> 2023-03-31 14:12:18 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-03-31 14:12:18 +0000
commit29c8bcf0e5fe9cdbf436535dfbd87d2ece4a038a (patch)
tree43712d435efb1504559b7158e0b428b7419ada3f
parent528dfcfe70f51cd1642f7f98b13d8fedc1d01f41 (diff)
parent002fcdc30dd233a368a25a91f724358c9fe1b9fa (diff)
Merge "Refresh profile and assign lead device as main device" into udc-dev
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java18
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java186
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java2
3 files changed, 131 insertions, 75 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index a3d632cfb82a..e884cf834722 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -305,10 +305,11 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
synchronized (mProfileLock) {
if (getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
for (CachedBluetoothDevice member : getMemberDevice()) {
- Log.d(TAG, "Disconnect the member(" + member.getAddress() + ")");
+ Log.d(TAG, "Disconnect the member:" + member);
member.disconnect();
}
}
+ Log.d(TAG, "Disconnect " + this);
mDevice.disconnect();
}
// Disconnect PBAP server in case its connected
@@ -440,11 +441,11 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
Log.d(TAG, "No profiles. Maybe we will connect later for device " + mDevice);
return;
}
-
+ Log.d(TAG, "connect " + this);
mDevice.connect();
if (getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
for (CachedBluetoothDevice member : getMemberDevice()) {
- Log.d(TAG, "connect the member(" + member.getAddress() + ")");
+ Log.d(TAG, "connect the member:" + member);
member.connect();
}
}
@@ -530,7 +531,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
// TODO: do any of these need to run async on a background thread?
- private void fillData() {
+ void fillData() {
updateProfiles();
fetchActiveDevices();
migratePhonebookPermissionChoice();
@@ -933,14 +934,15 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
@Override
public String toString() {
- return "CachedBluetoothDevice ("
+ return "CachedBluetoothDevice{"
+ "anonymizedAddress="
+ mDevice.getAnonymizedAddress()
+ ", name="
+ getName()
+ ", groupId="
+ mGroupId
- + ")";
+ + ", member=" + mMemberDevices
+ + "}";
}
@Override
@@ -1482,6 +1484,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
* Store the member devices that are in the same coordinated set.
*/
public void addMemberDevice(CachedBluetoothDevice memberDevice) {
+ Log.d(TAG, this + " addMemberDevice = " + memberDevice);
mMemberDevices.add(memberDevice);
}
@@ -1511,13 +1514,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
mDevice = newMainDevice.mDevice;
mRssi = newMainDevice.mRssi;
mJustDiscovered = newMainDevice.mJustDiscovered;
+ fillData();
// Set sub device from backup
newMainDevice.release();
newMainDevice.mDevice = tmpDevice;
newMainDevice.mRssi = tmpRssi;
newMainDevice.mJustDiscovered = tmpJustDiscovered;
- fetchActiveDevices();
+ newMainDevice.fillData();
}
/**
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
index 20a6cd8e09ce..356bb82a92e0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
@@ -71,7 +71,7 @@ public class CsipDeviceManager {
return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
}
- for (Map.Entry<Integer, ParcelUuid> entry: groupIdMap.entrySet()) {
+ for (Map.Entry<Integer, ParcelUuid> entry : groupIdMap.entrySet()) {
if (entry.getValue().equals(BluetoothUuid.CAP)) {
return entry.getKey();
}
@@ -153,72 +153,13 @@ public class CsipDeviceManager {
return;
}
log("onGroupIdChanged: mCachedDevices list =" + mCachedDevices.toString());
- final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
- final CachedBluetoothDeviceManager deviceManager = mBtManager.getCachedDeviceManager();
- final LeAudioProfile leAudioProfile = profileManager.getLeAudioProfile();
- final BluetoothDevice mainBluetoothDevice = (leAudioProfile != null && isAtLeastT()) ?
- leAudioProfile.getConnectedGroupLeadDevice(groupId) : null;
+ List<CachedBluetoothDevice> memberDevicesList = getMemberDevicesList(groupId);
CachedBluetoothDevice newMainDevice =
- mainBluetoothDevice != null ? deviceManager.findDevice(mainBluetoothDevice) : null;
- if (newMainDevice != null) {
- final CachedBluetoothDevice finalNewMainDevice = newMainDevice;
- final List<CachedBluetoothDevice> memberDevices = mCachedDevices.stream()
- .filter(cachedDevice -> !cachedDevice.equals(finalNewMainDevice)
- && cachedDevice.getGroupId() == groupId)
- .collect(Collectors.toList());
- if (memberDevices == null || memberDevices.isEmpty()) {
- log("onGroupIdChanged: There is no member device in list.");
- return;
- }
- log("onGroupIdChanged: removed from UI device =" + memberDevices
- + ", with groupId=" + groupId + " mainDevice= " + newMainDevice);
- for (CachedBluetoothDevice memberDeviceItem : memberDevices) {
- Set<CachedBluetoothDevice> memberSet = memberDeviceItem.getMemberDevice();
- if (!memberSet.isEmpty()) {
- log("onGroupIdChanged: Transfer the member list into new main device.");
- for (CachedBluetoothDevice memberListItem : memberSet) {
- if (!memberListItem.equals(newMainDevice)) {
- newMainDevice.addMemberDevice(memberListItem);
- }
- }
- memberSet.clear();
- }
-
- newMainDevice.addMemberDevice(memberDeviceItem);
- mCachedDevices.remove(memberDeviceItem);
- mBtManager.getEventManager().dispatchDeviceRemoved(memberDeviceItem);
- }
-
- if (!mCachedDevices.contains(newMainDevice)) {
- mCachedDevices.add(newMainDevice);
- mBtManager.getEventManager().dispatchDeviceAdded(newMainDevice);
- }
- } else {
- log("onGroupIdChanged: There is no main device from the LE profile.");
- int firstMatchedIndex = -1;
-
- for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
- final CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
- if (cachedDevice.getGroupId() != groupId) {
- continue;
- }
+ getPreferredMainDeviceWithoutConectionState(groupId, memberDevicesList);
- if (firstMatchedIndex == -1) {
- // Found the first one
- firstMatchedIndex = i;
- newMainDevice = cachedDevice;
- continue;
- }
-
- log("onGroupIdChanged: removed from UI device =" + cachedDevice
- + ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex);
-
- newMainDevice.addMemberDevice(cachedDevice);
- mCachedDevices.remove(i);
- mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
- break;
- }
- }
+ log("onGroupIdChanged: The mainDevice= " + newMainDevice
+ + " and the memberDevicesList of groupId= " + groupId + " =" + memberDevicesList);
+ addMemberDevicesIntoMainDevice(memberDevicesList, newMainDevice);
}
// @return {@code true}, the event is processed inside the method. It is for updating
@@ -263,7 +204,7 @@ public class CsipDeviceManager {
break;
}
- for (CachedBluetoothDevice device: memberSet) {
+ for (CachedBluetoothDevice device : memberSet) {
if (device.isConnected()) {
log("set device: " + device + " as the main device");
// Main device is disconnected and sub device is connected
@@ -296,7 +237,7 @@ public class CsipDeviceManager {
continue;
}
- for (CachedBluetoothDevice memberDevice: memberSet) {
+ for (CachedBluetoothDevice memberDevice : memberSet) {
if (memberDevice != null && memberDevice.equals(device)) {
return cachedDevice;
}
@@ -310,7 +251,6 @@ public class CsipDeviceManager {
* Check if the {@code groupId} is existed.
*
* @param groupId The group id
- *
* @return {@code true}, if we could find a device with this {@code groupId}; Otherwise,
* return {@code false}.
*/
@@ -322,6 +262,116 @@ public class CsipDeviceManager {
return false;
}
+ private List<CachedBluetoothDevice> getMemberDevicesList(int groupId) {
+ return mCachedDevices.stream()
+ .filter(cacheDevice -> cacheDevice.getGroupId() == groupId)
+ .collect(Collectors.toList());
+ }
+
+ private CachedBluetoothDevice getPreferredMainDeviceWithoutConectionState(int groupId,
+ List<CachedBluetoothDevice> memberDevicesList) {
+ // First, priority connected lead device from LE profile
+ // Second, the DUAL mode device which has A2DP/HFP and LE audio
+ // Last, any one of LE device in the list.
+ if (memberDevicesList == null || memberDevicesList.isEmpty()) {
+ return null;
+ }
+
+ final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
+ final CachedBluetoothDeviceManager deviceManager = mBtManager.getCachedDeviceManager();
+ final LeAudioProfile leAudioProfile = profileManager.getLeAudioProfile();
+ final BluetoothDevice mainBluetoothDevice = (leAudioProfile != null && isAtLeastT())
+ ? leAudioProfile.getConnectedGroupLeadDevice(groupId) : null;
+
+ if (mainBluetoothDevice != null) {
+ log("getPreferredMainDevice: The LeadDevice from LE profile is "
+ + mainBluetoothDevice.getAnonymizedAddress());
+ }
+
+ // 1st
+ CachedBluetoothDevice newMainDevice =
+ mainBluetoothDevice != null ? deviceManager.findDevice(mainBluetoothDevice) : null;
+ if (newMainDevice != null) {
+ if (newMainDevice.isConnected()) {
+ log("getPreferredMainDevice: The connected LeadDevice from LE profile");
+ return newMainDevice;
+ } else {
+ log("getPreferredMainDevice: The LeadDevice is not connect.");
+ }
+ } else {
+ log("getPreferredMainDevice: The LeadDevice is not in the all of devices list");
+ }
+
+ // 2nd
+ newMainDevice = memberDevicesList.stream()
+ .filter(cachedDevice -> cachedDevice.getConnectableProfiles().stream()
+ .anyMatch(profile -> profile instanceof A2dpProfile
+ || profile instanceof HeadsetProfile))
+ .findFirst().orElse(null);
+ if (newMainDevice != null) {
+ log("getPreferredMainDevice: The DUAL mode device");
+ return newMainDevice;
+ }
+
+ // last
+ if (!memberDevicesList.isEmpty()) {
+ newMainDevice = memberDevicesList.get(0);
+ }
+ return newMainDevice;
+ }
+
+ private void addMemberDevicesIntoMainDevice(List<CachedBluetoothDevice> memberDevicesList,
+ CachedBluetoothDevice newMainDevice) {
+ if (newMainDevice == null) {
+ log("addMemberDevicesIntoMainDevice: No main device. Do nothing.");
+ return;
+ }
+ if (memberDevicesList.isEmpty()) {
+ log("addMemberDevicesIntoMainDevice: No member device in list. Do nothing.");
+ return;
+ }
+ CachedBluetoothDevice mainDeviceOfNewMainDevice = findMainDevice(newMainDevice);
+ boolean isMemberInOtherMainDevice = mainDeviceOfNewMainDevice != null;
+ if (!memberDevicesList.contains(newMainDevice) && isMemberInOtherMainDevice) {
+ log("addMemberDevicesIntoMainDevice: The 'new main device' is not in list, and it is "
+ + "the member at other device. Do switch main and member.");
+ // To switch content and dispatch to notify UI change
+ mBtManager.getEventManager().dispatchDeviceRemoved(mainDeviceOfNewMainDevice);
+ mainDeviceOfNewMainDevice.switchMemberDeviceContent(newMainDevice);
+ mainDeviceOfNewMainDevice.refresh();
+ // It is necessary to do remove and add for updating the mapping on
+ // preference and device
+ mBtManager.getEventManager().dispatchDeviceAdded(mainDeviceOfNewMainDevice);
+ } else {
+ log("addMemberDevicesIntoMainDevice: Set new main device");
+ for (CachedBluetoothDevice memberDeviceItem : memberDevicesList) {
+ if (memberDeviceItem.equals(newMainDevice)) {
+ continue;
+ }
+ Set<CachedBluetoothDevice> memberSet = memberDeviceItem.getMemberDevice();
+ if (!memberSet.isEmpty()) {
+ for (CachedBluetoothDevice memberSetItem : memberSet) {
+ if (!memberSetItem.equals(newMainDevice)) {
+ newMainDevice.addMemberDevice(memberSetItem);
+ }
+ }
+ memberSet.clear();
+ }
+
+ newMainDevice.addMemberDevice(memberDeviceItem);
+ mCachedDevices.remove(memberDeviceItem);
+ mBtManager.getEventManager().dispatchDeviceRemoved(memberDeviceItem);
+ }
+
+ if (!mCachedDevices.contains(newMainDevice)) {
+ mCachedDevices.add(newMainDevice);
+ mBtManager.getEventManager().dispatchDeviceAdded(newMainDevice);
+ }
+ }
+ log("addMemberDevicesIntoMainDevice: After changed, CachedBluetoothDevice list: "
+ + mCachedDevices);
+ }
+
private void log(String msg) {
if (DEBUG) {
Log.d(TAG, msg);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 1c179f838586..6444f3bd4341 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -1150,9 +1150,11 @@ public class CachedBluetoothDeviceTest {
assertThat(mCachedDevice.mRssi).isEqualTo(RSSI_2);
assertThat(mCachedDevice.mJustDiscovered).isEqualTo(JUSTDISCOVERED_2);
assertThat(mCachedDevice.mDevice).isEqualTo(mSubDevice);
+ verify(mCachedDevice).fillData();
assertThat(mSubCachedDevice.mRssi).isEqualTo(RSSI_1);
assertThat(mSubCachedDevice.mJustDiscovered).isEqualTo(JUSTDISCOVERED_1);
assertThat(mSubCachedDevice.mDevice).isEqualTo(mDevice);
+ verify(mSubCachedDevice).fillData();
assertThat(mCachedDevice.getMemberDevice().contains(mSubCachedDevice)).isTrue();
}