Add estimated time remaining text to QS

- Add an API to BatteryController to get an estimated time remaining
string.
- BatteryController will now check up to once per minute what the
estimated time will be and builds the string using PowerUtil.
- If the "show percentage" setting is on, the estimated time remaining
string (and battery icon) will show next to the system icons in QS
- Also make the battery percent in QS obey the setting

Test: visual
Bug: 116481529
Change-Id: Iaafa00127c8b8baae40956254a1237c8b7ac079b
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 7221efa..ddcfbf6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -29,9 +29,14 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.fuelgauge.BatterySaverUtils;
+import com.android.settingslib.utils.PowerUtil;
+import com.android.systemui.Dependency;
+import com.android.systemui.power.EnhancedEstimates;
+import com.android.systemui.power.Estimate;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.text.NumberFormat;
 import java.util.ArrayList;
 
 /**
@@ -44,7 +49,9 @@
     public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
 
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final int UPDATE_GRANULARITY_MSEC = 1000 * 60;
 
+    private final EnhancedEstimates mEstimates = Dependency.get(EnhancedEstimates.class);
     private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
     private final PowerManager mPowerManager;
     private final Handler mHandler;
@@ -58,6 +65,8 @@
     protected boolean mAodPowerSave;
     private boolean mTestmode = false;
     private boolean mHasReceivedBattery = false;
+    private Estimate mEstimate;
+    private long mLastEstimateTimestamp = -1;
 
     public BatteryControllerImpl(Context context) {
         this(context, context.getSystemService(PowerManager.class));
@@ -71,6 +80,7 @@
 
         registerReceiver();
         updatePowerSave();
+        updateEstimate();
     }
 
     private void registerReceiver() {
@@ -180,6 +190,26 @@
         return mAodPowerSave;
     }
 
+    @Override
+    public String getEstimatedTimeRemainingString() {
+        if (mEstimate == null
+                || System.currentTimeMillis() > mLastEstimateTimestamp + UPDATE_GRANULARITY_MSEC) {
+            updateEstimate();
+        }
+        // Estimates may not exist yet even if we've checked
+        if (mEstimate == null) {
+            return null;
+        }
+        final String percentage = NumberFormat.getPercentInstance().format((double) mLevel / 100.0);
+        return PowerUtil.getBatteryRemainingShortStringFormatted(
+                mContext, mEstimate.estimateMillis);
+    }
+
+    private void updateEstimate() {
+        mEstimate = mEstimates.getEstimate();
+        mLastEstimateTimestamp = System.currentTimeMillis();
+    }
+
     private void updatePowerSave() {
         setPowerSave(mPowerManager.isPowerSaveMode());
     }