Merge "Get low battery level through metadata" into sc-dev
diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
index 096c2c5..bc5aa47 100644
--- a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
@@ -192,6 +192,7 @@
                 updateSubLayout(mLayoutPreference.findViewById(R.id.layout_middle),
                         BluetoothDevice.METADATA_MAIN_ICON,
                         BluetoothDevice.METADATA_MAIN_BATTERY,
+                        BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD,
                         BluetoothDevice.METADATA_MAIN_CHARGING,
                         /* titleResId */ 0,
                         MAIN_DEVICE_ID);
@@ -202,6 +203,7 @@
                 updateSubLayout(mLayoutPreference.findViewById(R.id.layout_left),
                         BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON,
                         BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY,
+                        BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD,
                         BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING,
                         R.string.bluetooth_left_name,
                         LEFT_DEVICE_ID);
@@ -209,6 +211,7 @@
                 updateSubLayout(mLayoutPreference.findViewById(R.id.layout_middle),
                         BluetoothDevice.METADATA_UNTETHERED_CASE_ICON,
                         BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY,
+                        BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD,
                         BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING,
                         R.string.bluetooth_middle_name,
                         CASE_DEVICE_ID);
@@ -216,6 +219,7 @@
                 updateSubLayout(mLayoutPreference.findViewById(R.id.layout_right),
                         BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON,
                         BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY,
+                        BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD,
                         BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING,
                         R.string.bluetooth_right_name,
                         RIGHT_DEVICE_ID);
@@ -243,7 +247,7 @@
     }
 
     private void updateSubLayout(LinearLayout linearLayout, int iconMetaKey, int batteryMetaKey,
-            int chargeMetaKey, int titleResId, int deviceId) {
+            int lowBatteryMetaKey, int chargeMetaKey, int titleResId, int deviceId) {
         if (linearLayout == null) {
             return;
         }
@@ -273,7 +277,15 @@
             linearLayout.setVisibility(View.VISIBLE);
             batterySummaryView.setText(com.android.settings.Utils.formatPercentage(batteryLevel));
             batterySummaryView.setVisibility(View.VISIBLE);
-            showBatteryIcon(linearLayout, batteryLevel, charging, batteryMetaKey);
+            int lowBatteryLevel = BluetoothUtils.getIntMetaData(bluetoothDevice, lowBatteryMetaKey);
+            if (lowBatteryLevel == BluetoothUtils.META_INT_ERROR) {
+                if (batteryMetaKey == BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY) {
+                    lowBatteryLevel = CASE_LOW_BATTERY_LEVEL;
+                } else {
+                    lowBatteryLevel = LOW_BATTERY_LEVEL;
+                }
+            }
+            showBatteryIcon(linearLayout, batteryLevel, lowBatteryLevel, charging);
         } else {
             if (deviceId == MAIN_DEVICE_ID) {
                 linearLayout.setVisibility(View.VISIBLE);
@@ -354,11 +366,8 @@
         });
     }
 
-    private void showBatteryIcon(LinearLayout linearLayout, int level, boolean charging,
-            int batteryMetaKey) {
-        final int lowBatteryLevel =
-                batteryMetaKey == BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY
-                ? CASE_LOW_BATTERY_LEVEL : LOW_BATTERY_LEVEL;
+    private void showBatteryIcon(LinearLayout linearLayout, int level, int lowBatteryLevel,
+            boolean charging) {
         final boolean enableLowBattery = level <= lowBatteryLevel && !charging;
         final ImageView imageView = linearLayout.findViewById(R.id.bt_battery_icon);
         if (enableLowBattery) {
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
index c8891e5..8e03d68 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
@@ -62,6 +62,9 @@
     private static final int BATTERY_LEVEL_RIGHT = 45;
     private static final int LOW_BATTERY_LEVEL = 15;
     private static final int CASE_LOW_BATTERY_LEVEL = 19;
+    private static final int LOW_BATTERY_LEVEL_THRESHOLD = 15;
+    private static final int BATTERY_LEVEL_5 = 5;
+    private static final int BATTERY_LEVEL_50 = 50;
     private static final String ICON_URI = "content://test.provider/icon.png";
     private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
 
@@ -202,6 +205,70 @@
     }
 
     @Test
+    public void refresh_underLowBatteryThreshold_showAlertIcon() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+                BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
+                String.valueOf(BATTERY_LEVEL_5).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD)).thenReturn(
+                String.valueOf(LOW_BATTERY_LEVEL_THRESHOLD).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_CHARGING)).thenReturn(
+                String.valueOf(false).getBytes());
+        when(mCachedDevice.isConnected()).thenReturn(true);
+
+        mController.refresh();
+
+        assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle),
+                R.drawable.ic_battery_alert_24dp);
+    }
+
+    @Test
+    public void refresh_underLowBatteryThresholdInCharging_showAlertIcon() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+                BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
+                String.valueOf(BATTERY_LEVEL_5).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD)).thenReturn(
+                String.valueOf(LOW_BATTERY_LEVEL_THRESHOLD).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_CHARGING)).thenReturn(
+                String.valueOf(true).getBytes());
+        when(mCachedDevice.isConnected()).thenReturn(true);
+
+        mController.refresh();
+
+        assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle), /* resId= */-1);
+    }
+
+    @Test
+    public void refresh_aboveLowBatteryThreshold_noAlertIcon() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn(
+                BluetoothDevice.DEVICE_TYPE_WATCH.getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(
+                String.valueOf(BATTERY_LEVEL_50).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD)).thenReturn(
+                String.valueOf(LOW_BATTERY_LEVEL_THRESHOLD).getBytes());
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_MAIN_CHARGING)).thenReturn(
+                String.valueOf(false).getBytes());
+        when(mCachedDevice.isConnected()).thenReturn(true);
+
+        mController.refresh();
+
+        assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle), /* resId= */-1);
+    }
+
+    @Test
     public void refresh_withLowBatteryAndUncharged_showAlertIcon() {
         when(mBluetoothDevice.getMetadata(
                 BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(