Loading android/app/src/com/android/bluetooth/bas/BatteryService.java +5 −2 Original line number Diff line number Diff line Loading @@ -61,7 +61,6 @@ public class BatteryService extends ProfileService { private static final int MAX_BATTERY_STATE_MACHINES = 10; private static BatteryService sBatteryService; private AdapterService mAdapterService; private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; Loading Loading @@ -177,7 +176,11 @@ public class BatteryService extends ProfileService { return sBatteryService; } private static synchronized void setBatteryService(BatteryService instance) { /** * Sets the battery service instance. It should be called only for testing purpose. */ @VisibleForTesting public static synchronized void setBatteryService(BatteryService instance) { if (DBG) { Log.d(TAG, "setBatteryService(): set to: " + instance); } Loading android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +11 −4 Original line number Diff line number Diff line Loading @@ -1217,8 +1217,8 @@ final class RemoteDevices { return; } if (intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED) == BluetoothProfile.STATE_DISCONNECTED) { // TODO: Rework this when non-HFP sources of battery level indication is added == BluetoothProfile.STATE_DISCONNECTED && !hasBatteryService(device)) { resetBatteryLevel(device); } } Loading Loading @@ -1381,6 +1381,13 @@ final class RemoteDevices { return batteryLevel * 100 / (numberOfLevels - 1); } @VisibleForTesting boolean hasBatteryService(BluetoothDevice device) { BatteryService batteryService = BatteryService.getBatteryService(); return batteryService != null && batteryService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED; } /** * Handles headset client connection state change event * @param intent must be {@link BluetoothHeadsetClient#ACTION_CONNECTION_STATE_CHANGED} intent Loading @@ -1393,8 +1400,8 @@ final class RemoteDevices { return; } if (intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED) == BluetoothProfile.STATE_DISCONNECTED) { // TODO: Rework this when non-HFP sources of battery level indication is added == BluetoothProfile.STATE_DISCONNECTED && !hasBatteryService(device)) { resetBatteryLevel(device); } } Loading android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java +90 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.Utils; import com.android.bluetooth.bas.BatteryService; import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; import com.android.bluetooth.hfp.HeadsetHalConstants; Loading Loading @@ -274,6 +275,43 @@ public class RemoteDevicesTest { verifyNoMoreInteractions(mAdapterService); } @Test public void testOnHeadsetStateChangeWithBatteryService_NotResetBatteryLevel() { int batteryLevel = 10; BatteryService oldBatteryService = setBatteryServiceForTesting(mDevice1); Assert.assertTrue(mRemoteDevices.hasBatteryService(mDevice1)); // Verify that device property is null initially Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that battery level is not reset mRemoteDevices.onHeadsetConnectionStateChanged( getHeadsetConnectionStateChangedIntent(mDevice1, BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_DISCONNECTED)); Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); Assert.assertEquals(batteryLevel, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); // Recover the previous battery service if exists clearBatteryServiceForTesting(oldBatteryService); verifyNoMoreInteractions(mAdapterService); } @Test @Ignore("b/266128644") public void testResetBatteryLevel_testAclStateChangeCallback() { Loading Loading @@ -506,6 +544,42 @@ public class RemoteDevicesTest { verifyNoMoreInteractions(mAdapterService); } @Test public void testHeadsetClientDisconnectedWithBatteryService_NotResetBatteryLevel() { int batteryLevel = 10; BatteryService oldBatteryService = setBatteryServiceForTesting(mDevice1); Assert.assertTrue(mRemoteDevices.hasBatteryService(mDevice1)); // Verify that device property is null initially Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that battery level is not reset. mRemoteDevices.onHeadsetClientConnectionStateChanged( getHeadsetClientConnectionStateChangedIntent(mDevice1, BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_DISCONNECTED)); Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); Assert.assertEquals(batteryLevel, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); clearBatteryServiceForTesting(oldBatteryService); verifyNoMoreInteractions(mAdapterService); } @Test public void testAGIndicatorParser_testCorrectValue() { int batteryLevel = 3; Loading Loading @@ -647,4 +721,20 @@ public class RemoteDevicesTest { return intent; } private static BatteryService setBatteryServiceForTesting(BluetoothDevice device) { BatteryService newService = mock(BatteryService.class); when(newService.getConnectionState(device)) .thenReturn(BluetoothProfile.STATE_CONNECTED); when(newService.isAvailable()).thenReturn(true); BatteryService oldService = BatteryService.getBatteryService(); BatteryService.setBatteryService(newService); return oldService; } private static void clearBatteryServiceForTesting(BatteryService service) { BatteryService.setBatteryService(service); } } Loading
android/app/src/com/android/bluetooth/bas/BatteryService.java +5 −2 Original line number Diff line number Diff line Loading @@ -61,7 +61,6 @@ public class BatteryService extends ProfileService { private static final int MAX_BATTERY_STATE_MACHINES = 10; private static BatteryService sBatteryService; private AdapterService mAdapterService; private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; Loading Loading @@ -177,7 +176,11 @@ public class BatteryService extends ProfileService { return sBatteryService; } private static synchronized void setBatteryService(BatteryService instance) { /** * Sets the battery service instance. It should be called only for testing purpose. */ @VisibleForTesting public static synchronized void setBatteryService(BatteryService instance) { if (DBG) { Log.d(TAG, "setBatteryService(): set to: " + instance); } Loading
android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +11 −4 Original line number Diff line number Diff line Loading @@ -1217,8 +1217,8 @@ final class RemoteDevices { return; } if (intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED) == BluetoothProfile.STATE_DISCONNECTED) { // TODO: Rework this when non-HFP sources of battery level indication is added == BluetoothProfile.STATE_DISCONNECTED && !hasBatteryService(device)) { resetBatteryLevel(device); } } Loading Loading @@ -1381,6 +1381,13 @@ final class RemoteDevices { return batteryLevel * 100 / (numberOfLevels - 1); } @VisibleForTesting boolean hasBatteryService(BluetoothDevice device) { BatteryService batteryService = BatteryService.getBatteryService(); return batteryService != null && batteryService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED; } /** * Handles headset client connection state change event * @param intent must be {@link BluetoothHeadsetClient#ACTION_CONNECTION_STATE_CHANGED} intent Loading @@ -1393,8 +1400,8 @@ final class RemoteDevices { return; } if (intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED) == BluetoothProfile.STATE_DISCONNECTED) { // TODO: Rework this when non-HFP sources of battery level indication is added == BluetoothProfile.STATE_DISCONNECTED && !hasBatteryService(device)) { resetBatteryLevel(device); } } Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java +90 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.Utils; import com.android.bluetooth.bas.BatteryService; import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; import com.android.bluetooth.hfp.HeadsetHalConstants; Loading Loading @@ -274,6 +275,43 @@ public class RemoteDevicesTest { verifyNoMoreInteractions(mAdapterService); } @Test public void testOnHeadsetStateChangeWithBatteryService_NotResetBatteryLevel() { int batteryLevel = 10; BatteryService oldBatteryService = setBatteryServiceForTesting(mDevice1); Assert.assertTrue(mRemoteDevices.hasBatteryService(mDevice1)); // Verify that device property is null initially Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that battery level is not reset mRemoteDevices.onHeadsetConnectionStateChanged( getHeadsetConnectionStateChangedIntent(mDevice1, BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_DISCONNECTED)); Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); Assert.assertEquals(batteryLevel, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); // Recover the previous battery service if exists clearBatteryServiceForTesting(oldBatteryService); verifyNoMoreInteractions(mAdapterService); } @Test @Ignore("b/266128644") public void testResetBatteryLevel_testAclStateChangeCallback() { Loading Loading @@ -506,6 +544,42 @@ public class RemoteDevicesTest { verifyNoMoreInteractions(mAdapterService); } @Test public void testHeadsetClientDisconnectedWithBatteryService_NotResetBatteryLevel() { int batteryLevel = 10; BatteryService oldBatteryService = setBatteryServiceForTesting(mDevice1); Assert.assertTrue(mRemoteDevices.hasBatteryService(mDevice1)); // Verify that device property is null initially Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), any(Bundle.class)); verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); // Verify that user can get battery level after the update Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), batteryLevel); // Verify that battery level is not reset. mRemoteDevices.onHeadsetClientConnectionStateChanged( getHeadsetClientConnectionStateChangedIntent(mDevice1, BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_DISCONNECTED)); Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); Assert.assertEquals(batteryLevel, mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); clearBatteryServiceForTesting(oldBatteryService); verifyNoMoreInteractions(mAdapterService); } @Test public void testAGIndicatorParser_testCorrectValue() { int batteryLevel = 3; Loading Loading @@ -647,4 +721,20 @@ public class RemoteDevicesTest { return intent; } private static BatteryService setBatteryServiceForTesting(BluetoothDevice device) { BatteryService newService = mock(BatteryService.class); when(newService.getConnectionState(device)) .thenReturn(BluetoothProfile.STATE_CONNECTED); when(newService.isAvailable()).thenReturn(true); BatteryService oldService = BatteryService.getBatteryService(); BatteryService.setBatteryService(newService); return oldService; } private static void clearBatteryServiceForTesting(BatteryService service) { BatteryService.setBatteryService(service); } }