Override 'online' status for kernel defender

Bug: 175614345
Test: 'atest HealthTestCases'
Merged-In: I2aae813163a319f1b0d4ac9fb143f586803e2618
Change-Id: I2aae813163a319f1b0d4ac9fb143f586803e2618
(cherry picked from commit 65e06412dd8f37f9c60bfbcc73a4c89ed1f37d7f)
diff --git a/health/BatteryDefender.cpp b/health/BatteryDefender.cpp
index 2cc538b..e11d1a9 100644
--- a/health/BatteryDefender.cpp
+++ b/health/BatteryDefender.cpp
@@ -172,19 +172,19 @@
 }
 
 void BatteryDefender::stateMachine_runAction(const state_E state,
-                                             struct android::BatteryProperties *props) {
+                                             const struct android::BatteryProperties *props) {
     switch (state) {
         case STATE_INIT:
             loadPersistentStorage();
-            mWasAcOnline = props->chargerAcOnline;
-            mWasUsbOnline = props->chargerUsbOnline;
+            if (props->chargerUsbOnline || props->chargerAcOnline) {
+                mWasAcOnline = props->chargerAcOnline;
+                mWasUsbOnline = props->chargerUsbOnline;
+            }
             break;
 
         case STATE_DISABLED:
         case STATE_DISCONNECTED:
             clearStateData();
-            mWasAcOnline = false;
-            mWasUsbOnline = false;
             break;
 
         case STATE_CONNECTED:
@@ -192,32 +192,11 @@
             if (props->batteryLevel == kChargeHighCapacityLevel) {
                 mHasReachedHighCapacityLevel = true;
             }
-
-            mWasAcOnline = props->chargerAcOnline;
-            mWasUsbOnline = props->chargerUsbOnline;
             break;
 
         case STATE_ACTIVE:
             addTimeToChargeTimers();
             mTimeActiveSecs += mTimeBetweenUpdateCalls;
-
-            /* Force online if active and still connected to power.
-             * Setting a charge limit below the current charge level may
-             * disable the adapter. This does not occur for wireless adapters.
-             */
-            if (mIsUsbPresent) {
-                /* If both previous fields are incorrectly false, force USB online */
-                if ((mWasAcOnline == false) && (mWasUsbOnline == false)) {
-                    props->chargerUsbOnline = true;
-                } else {
-                    if (mWasAcOnline) {
-                        props->chargerAcOnline = true;
-                    }
-                    if (mWasUsbOnline) {
-                        props->chargerUsbOnline = true;
-                    }
-                }
-            }
             break;
 
         default:
@@ -311,6 +290,38 @@
     }
 }
 
+void BatteryDefender::updateDefenderProperties(struct android::BatteryProperties *props) {
+    /**
+     * Override the OVERHEAT flag for UI updates to settings.
+     * Also, force AC/USB online if active and still connected to power.
+     */
+    if (mCurrentState == STATE_ACTIVE) {
+        props->batteryHealth = android::BATTERY_HEALTH_OVERHEAT;
+    }
+
+    /**
+     * If the kernel is forcing the input current limit to 0, then the online status may
+     * need to be overwritten. Also, setting a charge limit below the current charge level
+     * may disable the adapter. This does not occur for wireless adapters.
+     * Note; only override "online" if necessary (all "online"s are false).
+     */
+    if (props->chargerUsbOnline == false && props->chargerAcOnline == false) {
+        /* Override if the USB is connected and a battery defender is active */
+        if (mIsUsbPresent && props->batteryHealth == android::BATTERY_HEALTH_OVERHEAT) {
+            if (mWasAcOnline) {
+                props->chargerAcOnline = true;
+            }
+            if (mWasUsbOnline) {
+                props->chargerUsbOnline = true;
+            }
+        }
+    } else {
+        /* One of these booleans will always be true if updated here */
+        mWasAcOnline = props->chargerAcOnline;
+        mWasUsbOnline = props->chargerUsbOnline;
+    }
+}
+
 void BatteryDefender::update(struct android::BatteryProperties *props) {
     if (!props) {
         return;
@@ -326,13 +337,16 @@
     mTimeBetweenUpdateCalls = getDeltaTimeSeconds(&mTimePreviousSecs);
 
     // Run state machine
-    stateMachine_runAction(mCurrentState, props); /* May override battery properties */
+    stateMachine_runAction(mCurrentState, props);
     const state_E nextState = stateMachine_getNextState(mCurrentState);
     if (nextState != mCurrentState) {
         stateMachine_firstAction(nextState);
     }
     mCurrentState = nextState;
 
+    // Verify/update battery defender battery properties
+    updateDefenderProperties(props); /* May override battery properties */
+
     // Store outputs
     writeTimeToFile(kPathPersistChargerPresentTime, mTimeChargerPresentSecs,
                     &mTimeChargerPresentSecsPrevious);
diff --git a/health/include/pixelhealth/BatteryDefender.h b/health/include/pixelhealth/BatteryDefender.h
index acb1aba..bc64260 100644
--- a/health/include/pixelhealth/BatteryDefender.h
+++ b/health/include/pixelhealth/BatteryDefender.h
@@ -117,10 +117,11 @@
     int mChargeLevelStopPrevious = DEFAULT_CHARGE_LEVEL_STOP;
     bool mHasReachedHighCapacityLevel = false;
     bool mWasAcOnline = false;
-    bool mWasUsbOnline = false;
+    bool mWasUsbOnline = true; /* Default; in case neither AC/USB online becomes 1 */
 
     // Process state actions
-    void stateMachine_runAction(const state_E state, struct android::BatteryProperties *props);
+    void stateMachine_runAction(const state_E state,
+                                const struct android::BatteryProperties *props);
 
     // Check state transitions
     state_E stateMachine_getNextState(const state_E state);
@@ -128,6 +129,7 @@
     // Process state entry actions
     void stateMachine_firstAction(const state_E state);
 
+    void updateDefenderProperties(struct android::BatteryProperties *props);
     void clearStateData(void);
     void loadPersistentStorage(void);
     int64_t getTime(void);
diff --git a/health/test/TestBatteryDefender.cpp b/health/test/TestBatteryDefender.cpp
index 6058440..233dd72 100644
--- a/health/test/TestBatteryDefender.cpp
+++ b/health/test/TestBatteryDefender.cpp
@@ -417,7 +417,7 @@
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
     battDefender.update(&props);
     ASSERT_EQ(props.chargerAcOnline, false);
-    ASSERT_EQ(props.chargerUsbOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, true);
 
     props.chargerAcOnline = false;
     props.chargerUsbOnline = false;
@@ -517,7 +517,7 @@
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
     battDefender.update(&props);
     ASSERT_EQ(props.chargerAcOnline, false);
-    ASSERT_EQ(props.chargerUsbOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, true);
 
     props.chargerAcOnline = false;
     props.chargerUsbOnline = false;
@@ -610,6 +610,55 @@
     ASSERT_EQ(props.chargerUsbOnline, true);
 }
 
+TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_overrideHealth) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToConnectedCapacityReached();
+
+    InSequence s;
+
+    props.batteryHealth = android::BATTERY_HEALTH_UNKNOWN;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
+    battDefender.update(&props);
+    ASSERT_EQ(props.batteryHealth, android::BATTERY_HEALTH_UNKNOWN);
+
+    props.batteryHealth = android::BATTERY_HEALTH_UNKNOWN;
+    testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
+    battDefender.update(&props);
+    ASSERT_EQ(props.batteryHealth, android::BATTERY_HEALTH_OVERHEAT);
+}
+
+TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_kernelDefend) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToConnectedCapacityReached();
+
+    InSequence s;
+
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED")).Times(3);
+    battDefender.update(&props);
+
+    props.chargerAcOnline = true;
+    props.chargerUsbOnline = true;
+    props.batteryHealth = android::BATTERY_HEALTH_OVERHEAT;
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, true);
+    ASSERT_EQ(props.chargerUsbOnline, true);
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = false;
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, true);
+    ASSERT_EQ(props.chargerUsbOnline, true);
+}
+
 }  // namespace health
 }  // namespace pixel
 }  // namespace google