Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +17 −2 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Stream; /** * CachedBluetoothDevice represents a remote Bluetooth device. It contains Loading Loading @@ -652,6 +653,20 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return mDevice.getBatteryLevel(); } /** * Get the lowest battery level from remote device and its member devices * @return battery level in percentage [0-100] or * {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN} */ public int getMinBatteryLevelWithMemberDevices() { return Stream.concat(Stream.of(this), mMemberDevices.stream()) .mapToInt(cachedDevice -> cachedDevice.getBatteryLevel()) .filter(batteryLevel -> batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) .min() .orElse(BluetoothDevice.BATTERY_LEVEL_UNKNOWN); } void refresh() { ThreadUtils.postOnBackgroundThread(() -> { if (BluetoothUtils.isAdvancedDetailsHeader(mDevice)) { Loading Loading @@ -1147,7 +1162,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> // BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF, or BluetoothDevice.BATTERY_LEVEL_UNKNOWN, // any other value should be a framework bug. Thus assume here that if value is greater // than BluetoothDevice.BATTERY_LEVEL_UNKNOWN, it must be valid final int batteryLevel = getBatteryLevel(); final int batteryLevel = getMinBatteryLevelWithMemberDevices(); if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { // TODO: name com.android.settingslib.bluetooth.Utils something different batteryLevelPercentageString = Loading Loading @@ -1322,7 +1337,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> // BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF, or BluetoothDevice.BATTERY_LEVEL_UNKNOWN, // any other value should be a framework bug. Thus assume here that if value is greater // than BluetoothDevice.BATTERY_LEVEL_UNKNOWN, it must be valid final int batteryLevel = getBatteryLevel(); final int batteryLevel = getMinBatteryLevelWithMemberDevices(); if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { // TODO: name com.android.settingslib.bluetooth.Utils something different batteryLevelPercentageString = Loading packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -528,6 +528,51 @@ public class CachedBluetoothDeviceTest { assertThat(mCachedDevice.getConnectionSummary()).isNull(); } @Test public void getConnectionSummary_testMemberDevicesExist_returnMinBattery() { // One device is active with battery level 70. mBatteryLevel = 70; updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); // Add a member device with battery level 30. int lowerBatteryLevel = 30; mCachedDevice.addMemberDevice(mSubCachedDevice); doAnswer((invocation) -> lowerBatteryLevel).when(mSubCachedDevice).getBatteryLevel(); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active, 30% battery"); } @Test public void getConnectionSummary_testMemberDevicesBatteryUnknown_returnMinBattery() { // One device is active with battery level 70. mBatteryLevel = 70; updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); // Add a member device with battery level unknown. mCachedDevice.addMemberDevice(mSubCachedDevice); doAnswer((invocation) -> BluetoothDevice.BATTERY_LEVEL_UNKNOWN).when( mSubCachedDevice).getBatteryLevel(); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active, 70% battery"); } @Test public void getConnectionSummary_testAllDevicesBatteryUnknown_returnNoBattery() { // One device is active with battery level unknown. updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); // Add a member device with battery level unknown. mCachedDevice.addMemberDevice(mSubCachedDevice); doAnswer((invocation) -> BluetoothDevice.BATTERY_LEVEL_UNKNOWN).when( mSubCachedDevice).getBatteryLevel(); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); } @Test public void getConnectionSummary_testMultipleProfilesActiveDevice() { // Test without battery level Loading packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +1 −1 Original line number Diff line number Diff line Loading @@ -226,7 +226,7 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { listenToMetadata(device); } else { stopListeningToStaleDeviceMetadata(); batteryLevel = device.getBatteryLevel(); batteryLevel = device.getMinBatteryLevelWithMemberDevices(); } if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { Loading packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt +1 −1 Original line number Diff line number Diff line Loading @@ -168,7 +168,7 @@ class BluetoothTileTest : SysuiTestCase() { val btDevice = mock<BluetoothDevice>() whenever(cachedDevice2.device).thenReturn(btDevice) whenever(btDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(null) whenever(cachedDevice2.batteryLevel).thenReturn(25) whenever(cachedDevice2.minBatteryLevelWithMemberDevices).thenReturn(25) addConnectedDevice(cachedDevice2) tile.handleUpdateState(state, /* arg= */ null) Loading Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +17 −2 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Stream; /** * CachedBluetoothDevice represents a remote Bluetooth device. It contains Loading Loading @@ -652,6 +653,20 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return mDevice.getBatteryLevel(); } /** * Get the lowest battery level from remote device and its member devices * @return battery level in percentage [0-100] or * {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN} */ public int getMinBatteryLevelWithMemberDevices() { return Stream.concat(Stream.of(this), mMemberDevices.stream()) .mapToInt(cachedDevice -> cachedDevice.getBatteryLevel()) .filter(batteryLevel -> batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) .min() .orElse(BluetoothDevice.BATTERY_LEVEL_UNKNOWN); } void refresh() { ThreadUtils.postOnBackgroundThread(() -> { if (BluetoothUtils.isAdvancedDetailsHeader(mDevice)) { Loading Loading @@ -1147,7 +1162,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> // BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF, or BluetoothDevice.BATTERY_LEVEL_UNKNOWN, // any other value should be a framework bug. Thus assume here that if value is greater // than BluetoothDevice.BATTERY_LEVEL_UNKNOWN, it must be valid final int batteryLevel = getBatteryLevel(); final int batteryLevel = getMinBatteryLevelWithMemberDevices(); if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { // TODO: name com.android.settingslib.bluetooth.Utils something different batteryLevelPercentageString = Loading Loading @@ -1322,7 +1337,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> // BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF, or BluetoothDevice.BATTERY_LEVEL_UNKNOWN, // any other value should be a framework bug. Thus assume here that if value is greater // than BluetoothDevice.BATTERY_LEVEL_UNKNOWN, it must be valid final int batteryLevel = getBatteryLevel(); final int batteryLevel = getMinBatteryLevelWithMemberDevices(); if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { // TODO: name com.android.settingslib.bluetooth.Utils something different batteryLevelPercentageString = Loading
packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -528,6 +528,51 @@ public class CachedBluetoothDeviceTest { assertThat(mCachedDevice.getConnectionSummary()).isNull(); } @Test public void getConnectionSummary_testMemberDevicesExist_returnMinBattery() { // One device is active with battery level 70. mBatteryLevel = 70; updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); // Add a member device with battery level 30. int lowerBatteryLevel = 30; mCachedDevice.addMemberDevice(mSubCachedDevice); doAnswer((invocation) -> lowerBatteryLevel).when(mSubCachedDevice).getBatteryLevel(); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active, 30% battery"); } @Test public void getConnectionSummary_testMemberDevicesBatteryUnknown_returnMinBattery() { // One device is active with battery level 70. mBatteryLevel = 70; updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); // Add a member device with battery level unknown. mCachedDevice.addMemberDevice(mSubCachedDevice); doAnswer((invocation) -> BluetoothDevice.BATTERY_LEVEL_UNKNOWN).when( mSubCachedDevice).getBatteryLevel(); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active, 70% battery"); } @Test public void getConnectionSummary_testAllDevicesBatteryUnknown_returnNoBattery() { // One device is active with battery level unknown. updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); // Add a member device with battery level unknown. mCachedDevice.addMemberDevice(mSubCachedDevice); doAnswer((invocation) -> BluetoothDevice.BATTERY_LEVEL_UNKNOWN).when( mSubCachedDevice).getBatteryLevel(); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); } @Test public void getConnectionSummary_testMultipleProfilesActiveDevice() { // Test without battery level Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +1 −1 Original line number Diff line number Diff line Loading @@ -226,7 +226,7 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { listenToMetadata(device); } else { stopListeningToStaleDeviceMetadata(); batteryLevel = device.getBatteryLevel(); batteryLevel = device.getMinBatteryLevelWithMemberDevices(); } if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { Loading
packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt +1 −1 Original line number Diff line number Diff line Loading @@ -168,7 +168,7 @@ class BluetoothTileTest : SysuiTestCase() { val btDevice = mock<BluetoothDevice>() whenever(cachedDevice2.device).thenReturn(btDevice) whenever(btDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(null) whenever(cachedDevice2.batteryLevel).thenReturn(25) whenever(cachedDevice2.minBatteryLevelWithMemberDevices).thenReturn(25) addConnectedDevice(cachedDevice2) tile.handleUpdateState(state, /* arg= */ null) Loading