Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/BatteryLevelsInfo.kt 0 → 100644 +28 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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 /** * BatteryLevelsInfo contains the battery levels of different components of a bluetooth device. * The range of a valid battery level is [0-100], and -1 if the battery level is not applicable. */ data class BatteryLevelsInfo( val leftBatteryLevel: Int, val rightBatteryLevel: Int, val caseBatteryLevel: Int, val overallBatteryLevel: Int, ) No newline at end of file packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +88 −0 Original line number Diff line number Diff line Loading @@ -44,10 +44,12 @@ import android.text.style.ForegroundColorSpan; import android.util.Log; import android.util.LruCache; import android.util.Pair; import android.view.InputDevice; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.annotation.WorkerThread; import com.android.internal.util.ArrayUtils; import com.android.settingslib.R; Loading @@ -62,6 +64,7 @@ import com.google.common.util.concurrent.ListenableFuture; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; Loading Loading @@ -150,6 +153,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private boolean mIsHearingAidProfileConnectedFail = false; private boolean mIsLeAudioProfileConnectedFail = false; private boolean mUnpairing; @Nullable private final InputDevice mInputDevice; private final boolean mIsDeviceStylus; // Group second device for Hearing Aid private CachedBluetoothDevice mSubDevice; Loading Loading @@ -193,6 +199,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> mGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID; initDrawableCache(); mUnpairing = false; mInputDevice = BluetoothUtils.getInputDevice(mContext, getAddress()); mIsDeviceStylus = BluetoothUtils.isDeviceStylus(mInputDevice, this); } /** Clears any pending messages in the message queue. */ Loading Loading @@ -1622,6 +1630,86 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } } /** * Returns the battery levels of all components of the bluetooth device. If no battery info is * available then returns null. */ @WorkerThread @Nullable public BatteryLevelsInfo getBatteryLevelsInfo() { // Try getting the battery information from metadata. BatteryLevelsInfo metadataSourceBattery = getBatteryFromMetadata(); if (metadataSourceBattery != null) { return metadataSourceBattery; } // Get the battery information from Bluetooth service. return getBatteryFromBluetoothService(); } @Nullable private BatteryLevelsInfo getBatteryFromMetadata() { if (BluetoothUtils.getBooleanMetaData(mDevice, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) { // The device is untethered headset, containing both earbuds and case. int leftBattery = BluetoothUtils.getIntMetaData( mDevice, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY); int rightBattery = BluetoothUtils.getIntMetaData( mDevice, BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY); int caseBattery = BluetoothUtils.getIntMetaData( mDevice, BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY); if (leftBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN && rightBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN && caseBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { Log.d(TAG, "No battery info from metadata is available for untethered device " + mDevice.getAnonymizedAddress()); return null; } else { int overallBattery = Arrays.stream(new int[]{leftBattery, rightBattery, caseBattery}) .filter(battery -> battery > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) .min() .orElse(BluetoothDevice.BATTERY_LEVEL_UNKNOWN); Log.d(TAG, "Acquired battery info from metadata for untethered device " + mDevice.getAnonymizedAddress() + " left earbud battery: " + leftBattery + " right earbud battery: " + rightBattery + " case battery: " + caseBattery + " overall battery: " + overallBattery); return new BatteryLevelsInfo( leftBattery, rightBattery, caseBattery, overallBattery); } } else if (mInputDevice != null || mIsDeviceStylus) { // The device is input device, using METADATA_MAIN_BATTERY field to get battery info. int overallBattery = BluetoothUtils.getIntMetaData( mDevice, BluetoothDevice.METADATA_MAIN_BATTERY); if (overallBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { Log.d(TAG, "No battery info from metadata is available for input device " + mDevice.getAnonymizedAddress()); return null; } else { Log.d(TAG, "Acquired battery info from metadata for input device " + mDevice.getAnonymizedAddress() + " overall battery: " + overallBattery); return new BatteryLevelsInfo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, overallBattery); } } return null; } @Nullable private BatteryLevelsInfo getBatteryFromBluetoothService() { // TODO(b/397847825): Implement the logic to get battery from Bluetooth service. return null; } private CharSequence getTvBatterySummary(int mainBattery, int leftBattery, int rightBattery, int lowBatteryColorRes) { // Since there doesn't seem to be a way to use format strings to add the Loading packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +76 −0 Original line number Diff line number Diff line Loading @@ -40,12 +40,14 @@ import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.graphics.drawable.BitmapDrawable; import android.hardware.input.InputManager; import android.media.AudioManager; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.text.Spannable; import android.text.style.ForegroundColorSpan; import android.util.LruCache; import android.view.InputDevice; import com.android.settingslib.R; import com.android.settingslib.media.flags.Flags; Loading Loading @@ -77,8 +79,10 @@ public class CachedBluetoothDeviceTest { private static final String DEVICE_ALIAS_NEW = "TestAliasNew"; private static final String TWS_BATTERY_LEFT = "15"; private static final String TWS_BATTERY_RIGHT = "25"; private static final String TWS_BATTERY_CASE = "10"; private static final String TWS_LOW_BATTERY_THRESHOLD_LOW = "10"; private static final String TWS_LOW_BATTERY_THRESHOLD_HIGH = "25"; private static final String MAIN_BATTERY = "80"; private static final String TEMP_BOND_METADATA = "<TEMP_BOND_TYPE>le_audio_sharing</TEMP_BOND_TYPE>"; private static final short RSSI_1 = 10; Loading @@ -87,6 +91,8 @@ public class CachedBluetoothDeviceTest { private static final boolean JUSTDISCOVERED_2 = false; private static final int LOW_BATTERY_COLOR = android.R.color.holo_red_dark; private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25; private static final int TEST_DEVICE_ID = 123; private final InputDevice mInputDevice = mock(InputDevice.class); @Mock private LocalBluetoothProfileManager mProfileManager; @Mock Loading Loading @@ -116,6 +122,8 @@ public class CachedBluetoothDeviceTest { private LocalBluetoothLeBroadcastAssistant mAssistant; @Mock private BluetoothLeBroadcastReceiveState mLeBroadcastReceiveState; @Mock private InputManager mInputManager; private CachedBluetoothDevice mCachedDevice; private CachedBluetoothDevice mSubCachedDevice; private AudioManager mAudioManager; Loading Loading @@ -2175,6 +2183,74 @@ public class CachedBluetoothDeviceTest { assertThat(mCachedDevice.isHearingDevice()).isFalse(); } @Test public void getBatteryLevelsInfo_untetheredHeadsetWithBattery_returnBatteryLevelsInfo() { when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( "true".getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn( TWS_BATTERY_LEFT.getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn( TWS_BATTERY_RIGHT.getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY)).thenReturn( TWS_BATTERY_CASE.getBytes()); BatteryLevelsInfo batteryLevelsInfo = mCachedDevice.getBatteryLevelsInfo(); assertThat(batteryLevelsInfo.getLeftBatteryLevel()).isEqualTo( Integer.parseInt(TWS_BATTERY_LEFT)); assertThat(batteryLevelsInfo.getRightBatteryLevel()).isEqualTo( Integer.parseInt(TWS_BATTERY_RIGHT)); assertThat(batteryLevelsInfo.getCaseBatteryLevel()).isEqualTo( Integer.parseInt(TWS_BATTERY_CASE)); assertThat(batteryLevelsInfo.getOverallBatteryLevel()).isEqualTo( Integer.parseInt(TWS_BATTERY_CASE)); } @Test public void getBatteryLevelsInfo_inputDeviceWithBattery_returnBatteryLevelsInfo() { when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( "false".getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn( MAIN_BATTERY.getBytes()); when(mContext.getSystemService(InputManager.class)).thenReturn(mInputManager); when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{TEST_DEVICE_ID}); when(mInputManager.getInputDeviceBluetoothAddress(TEST_DEVICE_ID)).thenReturn( DEVICE_ADDRESS); when(mInputManager.getInputDevice(TEST_DEVICE_ID)).thenReturn(mInputDevice); BatteryLevelsInfo batteryLevelsInfo = mCachedDevice.getBatteryLevelsInfo(); assertThat(batteryLevelsInfo.getLeftBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getRightBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getCaseBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getOverallBatteryLevel()).isEqualTo( Integer.parseInt(MAIN_BATTERY)); } @Test public void getBatteryLevelsInfo_stylusDeviceWithBattery_returnBatteryLevelsInfo() { when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( "false".getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn( BluetoothDevice.DEVICE_TYPE_STYLUS.getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn( MAIN_BATTERY.getBytes()); BatteryLevelsInfo batteryLevelsInfo = mCachedDevice.getBatteryLevelsInfo(); assertThat(batteryLevelsInfo.getLeftBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getRightBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getCaseBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getOverallBatteryLevel()).isEqualTo( Integer.parseInt(MAIN_BATTERY)); } private void updateProfileStatus(LocalBluetoothProfile profile, int status) { doReturn(status).when(profile).getConnectionStatus(mDevice); mCachedDevice.onProfileStateChanged(profile, status); Loading Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/BatteryLevelsInfo.kt 0 → 100644 +28 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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 /** * BatteryLevelsInfo contains the battery levels of different components of a bluetooth device. * The range of a valid battery level is [0-100], and -1 if the battery level is not applicable. */ data class BatteryLevelsInfo( val leftBatteryLevel: Int, val rightBatteryLevel: Int, val caseBatteryLevel: Int, val overallBatteryLevel: Int, ) No newline at end of file
packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +88 −0 Original line number Diff line number Diff line Loading @@ -44,10 +44,12 @@ import android.text.style.ForegroundColorSpan; import android.util.Log; import android.util.LruCache; import android.util.Pair; import android.view.InputDevice; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.annotation.WorkerThread; import com.android.internal.util.ArrayUtils; import com.android.settingslib.R; Loading @@ -62,6 +64,7 @@ import com.google.common.util.concurrent.ListenableFuture; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; Loading Loading @@ -150,6 +153,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private boolean mIsHearingAidProfileConnectedFail = false; private boolean mIsLeAudioProfileConnectedFail = false; private boolean mUnpairing; @Nullable private final InputDevice mInputDevice; private final boolean mIsDeviceStylus; // Group second device for Hearing Aid private CachedBluetoothDevice mSubDevice; Loading Loading @@ -193,6 +199,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> mGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID; initDrawableCache(); mUnpairing = false; mInputDevice = BluetoothUtils.getInputDevice(mContext, getAddress()); mIsDeviceStylus = BluetoothUtils.isDeviceStylus(mInputDevice, this); } /** Clears any pending messages in the message queue. */ Loading Loading @@ -1622,6 +1630,86 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } } /** * Returns the battery levels of all components of the bluetooth device. If no battery info is * available then returns null. */ @WorkerThread @Nullable public BatteryLevelsInfo getBatteryLevelsInfo() { // Try getting the battery information from metadata. BatteryLevelsInfo metadataSourceBattery = getBatteryFromMetadata(); if (metadataSourceBattery != null) { return metadataSourceBattery; } // Get the battery information from Bluetooth service. return getBatteryFromBluetoothService(); } @Nullable private BatteryLevelsInfo getBatteryFromMetadata() { if (BluetoothUtils.getBooleanMetaData(mDevice, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) { // The device is untethered headset, containing both earbuds and case. int leftBattery = BluetoothUtils.getIntMetaData( mDevice, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY); int rightBattery = BluetoothUtils.getIntMetaData( mDevice, BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY); int caseBattery = BluetoothUtils.getIntMetaData( mDevice, BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY); if (leftBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN && rightBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN && caseBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { Log.d(TAG, "No battery info from metadata is available for untethered device " + mDevice.getAnonymizedAddress()); return null; } else { int overallBattery = Arrays.stream(new int[]{leftBattery, rightBattery, caseBattery}) .filter(battery -> battery > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) .min() .orElse(BluetoothDevice.BATTERY_LEVEL_UNKNOWN); Log.d(TAG, "Acquired battery info from metadata for untethered device " + mDevice.getAnonymizedAddress() + " left earbud battery: " + leftBattery + " right earbud battery: " + rightBattery + " case battery: " + caseBattery + " overall battery: " + overallBattery); return new BatteryLevelsInfo( leftBattery, rightBattery, caseBattery, overallBattery); } } else if (mInputDevice != null || mIsDeviceStylus) { // The device is input device, using METADATA_MAIN_BATTERY field to get battery info. int overallBattery = BluetoothUtils.getIntMetaData( mDevice, BluetoothDevice.METADATA_MAIN_BATTERY); if (overallBattery <= BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { Log.d(TAG, "No battery info from metadata is available for input device " + mDevice.getAnonymizedAddress()); return null; } else { Log.d(TAG, "Acquired battery info from metadata for input device " + mDevice.getAnonymizedAddress() + " overall battery: " + overallBattery); return new BatteryLevelsInfo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, overallBattery); } } return null; } @Nullable private BatteryLevelsInfo getBatteryFromBluetoothService() { // TODO(b/397847825): Implement the logic to get battery from Bluetooth service. return null; } private CharSequence getTvBatterySummary(int mainBattery, int leftBattery, int rightBattery, int lowBatteryColorRes) { // Since there doesn't seem to be a way to use format strings to add the Loading
packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +76 −0 Original line number Diff line number Diff line Loading @@ -40,12 +40,14 @@ import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.graphics.drawable.BitmapDrawable; import android.hardware.input.InputManager; import android.media.AudioManager; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.text.Spannable; import android.text.style.ForegroundColorSpan; import android.util.LruCache; import android.view.InputDevice; import com.android.settingslib.R; import com.android.settingslib.media.flags.Flags; Loading Loading @@ -77,8 +79,10 @@ public class CachedBluetoothDeviceTest { private static final String DEVICE_ALIAS_NEW = "TestAliasNew"; private static final String TWS_BATTERY_LEFT = "15"; private static final String TWS_BATTERY_RIGHT = "25"; private static final String TWS_BATTERY_CASE = "10"; private static final String TWS_LOW_BATTERY_THRESHOLD_LOW = "10"; private static final String TWS_LOW_BATTERY_THRESHOLD_HIGH = "25"; private static final String MAIN_BATTERY = "80"; private static final String TEMP_BOND_METADATA = "<TEMP_BOND_TYPE>le_audio_sharing</TEMP_BOND_TYPE>"; private static final short RSSI_1 = 10; Loading @@ -87,6 +91,8 @@ public class CachedBluetoothDeviceTest { private static final boolean JUSTDISCOVERED_2 = false; private static final int LOW_BATTERY_COLOR = android.R.color.holo_red_dark; private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25; private static final int TEST_DEVICE_ID = 123; private final InputDevice mInputDevice = mock(InputDevice.class); @Mock private LocalBluetoothProfileManager mProfileManager; @Mock Loading Loading @@ -116,6 +122,8 @@ public class CachedBluetoothDeviceTest { private LocalBluetoothLeBroadcastAssistant mAssistant; @Mock private BluetoothLeBroadcastReceiveState mLeBroadcastReceiveState; @Mock private InputManager mInputManager; private CachedBluetoothDevice mCachedDevice; private CachedBluetoothDevice mSubCachedDevice; private AudioManager mAudioManager; Loading Loading @@ -2175,6 +2183,74 @@ public class CachedBluetoothDeviceTest { assertThat(mCachedDevice.isHearingDevice()).isFalse(); } @Test public void getBatteryLevelsInfo_untetheredHeadsetWithBattery_returnBatteryLevelsInfo() { when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( "true".getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn( TWS_BATTERY_LEFT.getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn( TWS_BATTERY_RIGHT.getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY)).thenReturn( TWS_BATTERY_CASE.getBytes()); BatteryLevelsInfo batteryLevelsInfo = mCachedDevice.getBatteryLevelsInfo(); assertThat(batteryLevelsInfo.getLeftBatteryLevel()).isEqualTo( Integer.parseInt(TWS_BATTERY_LEFT)); assertThat(batteryLevelsInfo.getRightBatteryLevel()).isEqualTo( Integer.parseInt(TWS_BATTERY_RIGHT)); assertThat(batteryLevelsInfo.getCaseBatteryLevel()).isEqualTo( Integer.parseInt(TWS_BATTERY_CASE)); assertThat(batteryLevelsInfo.getOverallBatteryLevel()).isEqualTo( Integer.parseInt(TWS_BATTERY_CASE)); } @Test public void getBatteryLevelsInfo_inputDeviceWithBattery_returnBatteryLevelsInfo() { when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( "false".getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn( MAIN_BATTERY.getBytes()); when(mContext.getSystemService(InputManager.class)).thenReturn(mInputManager); when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{TEST_DEVICE_ID}); when(mInputManager.getInputDeviceBluetoothAddress(TEST_DEVICE_ID)).thenReturn( DEVICE_ADDRESS); when(mInputManager.getInputDevice(TEST_DEVICE_ID)).thenReturn(mInputDevice); BatteryLevelsInfo batteryLevelsInfo = mCachedDevice.getBatteryLevelsInfo(); assertThat(batteryLevelsInfo.getLeftBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getRightBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getCaseBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getOverallBatteryLevel()).isEqualTo( Integer.parseInt(MAIN_BATTERY)); } @Test public void getBatteryLevelsInfo_stylusDeviceWithBattery_returnBatteryLevelsInfo() { when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( "false".getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn( BluetoothDevice.DEVICE_TYPE_STYLUS.getBytes()); when(mDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn( MAIN_BATTERY.getBytes()); BatteryLevelsInfo batteryLevelsInfo = mCachedDevice.getBatteryLevelsInfo(); assertThat(batteryLevelsInfo.getLeftBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getRightBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getCaseBatteryLevel()).isEqualTo( BluetoothDevice.BATTERY_LEVEL_UNKNOWN); assertThat(batteryLevelsInfo.getOverallBatteryLevel()).isEqualTo( Integer.parseInt(MAIN_BATTERY)); } private void updateProfileStatus(LocalBluetoothProfile profile, int status) { doReturn(status).when(profile).getConnectionStatus(mDevice); mCachedDevice.onProfileStateChanged(profile, status); Loading