health: Implement new charging control battery listener

Change-Id: I78af47eb726b42d1ba6753d73acb92c31d951c6d
diff --git a/src/org/omnirom/omnilib/internal/health/ChargingControlController.java b/src/org/omnirom/omnilib/internal/health/ChargingControlController.java
index 534276b..48edcbd 100644
--- a/src/org/omnirom/omnilib/internal/health/ChargingControlController.java
+++ b/src/org/omnirom/omnilib/internal/health/ChargingControlController.java
@@ -47,6 +47,7 @@
     private ChargingControlNotification mChargingNotification;
     private OmniRomHealthBatteryBroadcastReceiver mBattReceiver;
     private BroadcastReceiver mAlarmBroadcastReceiver;
+    private boolean mIsEnabled = false;
 
     // Defaults
     private boolean mDefaultEnabled = false;
@@ -236,6 +237,43 @@
                 && setStartTime(mDefaultStartTime) && setTargetTime(mDefaultTargetTime);
     }
 
+    private void updateBatteryInfo(Intent intent) {
+        int battStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
+        int battPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+
+        if (battStatus == BatteryManager.BATTERY_STATUS_FULL) {
+            mIsControlCancelledOnce = false;
+        }
+
+        if (mCurrentProvider.requiresBatteryLevelMonitoring()) {
+            mIsPowerConnected = true;
+        } else {
+            mIsPowerConnected =
+                    battPlugged != 0 || (battStatus != BatteryManager.BATTERY_STATUS_DISCHARGING &&
+                            battStatus != BatteryManager.BATTERY_STATUS_UNKNOWN);
+        }
+
+        int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
+        int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
+        if (level == -1 || scale == -1) {
+            return;
+        }
+
+        mBatteryPct = level * 100 / (float) scale;
+
+        Log.i(TAG, "mIsPowerConnected: " + mIsPowerConnected + ", mBatteryPct: " + mBatteryPct);
+    }
+
+    private void updateBatteryInfo() {
+        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+        Intent batteryStatus = mContext.registerReceiver(null, ifilter);
+        if (batteryStatus == null) {
+            Log.e(TAG, "batteryStatus is NULL!");
+            return;
+        }
+        updateBatteryInfo(batteryStatus);
+    }
+
     @Override
     public void onStart() {
         if (mChargingControl == null) {
@@ -245,46 +283,6 @@
         // Register setting observer
         registerSettings(MODE_URI, LIMIT_URI, ENABLED_URI, START_TIME_URI, TARGET_TIME_URI);
 
-        // For devices that do not support bypass, we can only always listen to battery change
-        // because we can't distinguish between "unplugged" and "plugged in but not charging".
-        if (mCurrentProvider.requiresBatteryLevelMonitoring()) {
-            mIsPowerConnected = true;
-            onPowerStatus(true);
-            handleSettingChange();
-            return;
-        }
-
-        // Start monitor battery status when power connected
-        IntentFilter connectedFilter = new IntentFilter(Intent.ACTION_POWER_CONNECTED);
-        mContext.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                Log.i(TAG, "Power connected, start monitoring battery");
-                mIsPowerConnected = true;
-                onPowerStatus(true);
-            }
-        }, connectedFilter);
-
-        // Stop monitor battery status when power disconnected
-        IntentFilter disconnectedFilter = new IntentFilter(Intent.ACTION_POWER_DISCONNECTED);
-        mContext.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                Log.i(TAG, "Power disconnected, stop monitoring battery");
-                mIsPowerConnected = false;
-                onPowerStatus(false);
-            }
-        }, disconnectedFilter);
-
-        // Initial monitor
-        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-        Intent batteryStatus = mContext.registerReceiver(null, ifilter);
-        mIsPowerConnected = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0;
-        if (mIsPowerConnected) {
-            onPowerConnected();
-        }
-
-        // Restore settings
         handleSettingChange();
     }
 
@@ -474,6 +472,27 @@
     private void handleSettingChange() {
         int mode = getMode();
 
+        if (mIsEnabled != isEnabled()) {
+            mIsEnabled = isEnabled();
+
+            if (mIsEnabled) {
+                if (mBattReceiver == null) {
+                    mBattReceiver = new OmniRomHealthBatteryBroadcastReceiver();
+                } else {
+                    mContext.unregisterReceiver(mBattReceiver);
+                }
+                IntentFilter battFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+                mContext.registerReceiver(mBattReceiver, battFilter);
+                Log.i(TAG, "Enabled charging control, start monitoring battery");
+            } else {
+                if (mBattReceiver != null) {
+                    mContext.unregisterReceiver(mBattReceiver);
+                    mBattReceiver = null;
+                }
+                Log.i(TAG, "Disabled charging control, stop monitoring battery");
+            }
+        }
+
         if (!isProvideSupportCCMode(mode)) {
             Log.e(TAG, "Current provider does not support mode: " + mode
                     + ", setting to default mode");
@@ -483,6 +502,9 @@
         // Reset internal states
         resetInternalState();
 
+        // Update battery info
+        updateBatteryInfo();
+
         // Update based on those values
         updateChargeControl();
     }
@@ -503,6 +525,7 @@
         pw.println("  TargetTime: " + getTargetTime());
         pw.println();
         pw.println("ChargingControlController State:");
+        pw.println("  mIsEnabled: " + mIsEnabled);
         pw.println("  mBatteryPct: " + mBatteryPct);
         pw.println("  mIsPowerConnected: " + mIsPowerConnected);
         pw.println("  mIsNotificationPosted: " + mChargingNotification.isPosted());
@@ -516,13 +539,7 @@
     private class OmniRomHealthBatteryBroadcastReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
-            int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
-            int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
-            if (level == -1 || scale == -1) {
-                return;
-            }
-
-            mBatteryPct = level * 100 / (float) scale;
+            updateBatteryInfo(intent);
             updateChargeControl();
         }
     }