Override the 'online' status for AC/USB for battery defender

Conditions:
- The USB is connected
- The Battery Defender is active

Bug: 175614345
Test: 'atest HealthTestCases'
Merged-In: I3e72a6a4be71df27c2b7965533810f8981c36e37
Change-Id: I3e72a6a4be71df27c2b7965533810f8981c36e37
(cherry picked from commit 8a3eade1ca387d8fa54680b87774ed64b84c1cde)
diff --git a/health/Android.bp b/health/Android.bp
index b563b43..e954ca3 100644
--- a/health/Android.bp
+++ b/health/Android.bp
@@ -58,6 +58,7 @@
     static_libs: [
         "libgmock",
         "libpixelhealth",
+        "libbatterymonitor",
     ],
 
     shared_libs: [
diff --git a/health/BatteryDefender.cpp b/health/BatteryDefender.cpp
index e7e80c4..2cc538b 100644
--- a/health/BatteryDefender.cpp
+++ b/health/BatteryDefender.cpp
@@ -133,14 +133,12 @@
     }
 }
 
-bool BatteryDefender::isChargePowerAvailable(void) {
-    // USB presence is an indicator of connectivity
-    const bool chargerPresentWired = readFileToInt(kPathWiredChargerPresent) != 0;
+bool BatteryDefender::isChargePowerAvailable(const bool chargerWirelessOnline) {
+    // USB presence is an indicator of power availability
+    const bool chargerPresentWired = readFileToInt(kPathUSBChargerPresent) != 0;
+    mIsUsbPresent = chargerPresentWired;
 
-    // Wireless online is an indicator of a device having charge power
-    const bool chargerOnlineWireless = readFileToInt(kPathWirelessChargerOnline) != 0;
-
-    return chargerPresentWired || chargerOnlineWireless;
+    return chargerPresentWired || chargerWirelessOnline;
 }
 
 bool BatteryDefender::isDefaultChargeLevel(const int start, const int stop) {
@@ -173,27 +171,53 @@
                                          (int32_t)ONE_MIN_IN_SECONDS, INT32_MAX);
 }
 
-void BatteryDefender::stateMachine_runAction(const state_E state) {
+void BatteryDefender::stateMachine_runAction(const state_E state,
+                                             struct android::BatteryProperties *props) {
     switch (state) {
         case STATE_INIT:
             loadPersistentStorage();
+            mWasAcOnline = props->chargerAcOnline;
+            mWasUsbOnline = props->chargerUsbOnline;
             break;
 
         case STATE_DISABLED:
         case STATE_DISCONNECTED:
             clearStateData();
+            mWasAcOnline = false;
+            mWasUsbOnline = false;
             break;
 
         case STATE_CONNECTED:
             addTimeToChargeTimers();
-            if (readFileToInt(kPathBatteryCapacity) == kChargeHighCapacityLevel) {
+            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:
@@ -259,9 +283,8 @@
 void BatteryDefender::stateMachine_firstAction(const state_E state) {
     switch (state) {
         case STATE_DISABLED:
-            clearStateData();
             LOG(INFO) << "Disabled!";
-            break;
+            FALLTHROUGH_INTENDED;
 
         case STATE_DISCONNECTED:
             clearStateData();
@@ -288,18 +311,22 @@
     }
 }
 
-void BatteryDefender::update(void) {
+void BatteryDefender::update(struct android::BatteryProperties *props) {
+    if (!props) {
+        return;
+    }
+
     // Update module inputs
     const int chargeLevelVendorStart =
             android::base::GetIntProperty(kPropChargeLevelVendorStart, kChargeLevelDefaultStart);
     const int chargeLevelVendorStop =
             android::base::GetIntProperty(kPropChargeLevelVendorStop, kChargeLevelDefaultStop);
     mIsDefenderDisabled = isBatteryDefenderDisabled(chargeLevelVendorStart, chargeLevelVendorStop);
-    mIsPowerAvailable = isChargePowerAvailable();
+    mIsPowerAvailable = isChargePowerAvailable(props->chargerWirelessOnline);
     mTimeBetweenUpdateCalls = getDeltaTimeSeconds(&mTimePreviousSecs);
 
     // Run state machine
-    stateMachine_runAction(mCurrentState);
+    stateMachine_runAction(mCurrentState, props); /* May override battery properties */
     const state_E nextState = stateMachine_getNextState(mCurrentState);
     if (nextState != mCurrentState) {
         stateMachine_firstAction(nextState);
diff --git a/health/include/pixelhealth/BatteryDefender.h b/health/include/pixelhealth/BatteryDefender.h
index 3f9bb1c..31b410d 100644
--- a/health/include/pixelhealth/BatteryDefender.h
+++ b/health/include/pixelhealth/BatteryDefender.h
@@ -17,6 +17,8 @@
 #ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_BATTERYDEFENDER_H
 #define HARDWARE_GOOGLE_PIXEL_HEALTH_BATTERYDEFENDER_H
 
+#include <batteryservice/BatteryService.h>
+
 #include <stdbool.h>
 #include <time.h>
 #include <string>
@@ -50,7 +52,7 @@
                     const int32_t timeToClearTimerSecs = DEFAULT_TIME_TO_CLEAR_SECONDS);
 
     // This function shall be called periodically in HealthService
-    void update(void);
+    void update(struct android::BatteryProperties *props);
 
   private:
     enum state_E {
@@ -75,9 +77,7 @@
     const int32_t kTimeToClearTimerSecs;
 
     // Sysfs
-    const char *const kPathWirelessChargerOnline = "/sys/class/power_supply/wireless/online";
-    const char *const kPathWiredChargerPresent = "/sys/class/power_supply/usb/present";
-    const char *const kPathBatteryCapacity = "/sys/class/power_supply/battery/capacity";
+    const char *const kPathUSBChargerPresent = "/sys/class/power_supply/usb/present";
     const char *const kPathPersistChargerPresentTime =
             "/mnt/vendor/persist/battery/defender_charger_time";
     const char *const kPathPersistDefenderActiveTime =
@@ -101,6 +101,7 @@
     // Inputs
     int64_t mTimeBetweenUpdateCalls = 0;
     int64_t mTimePreviousSecs;
+    bool mIsUsbPresent = false;
     bool mIsPowerAvailable = false;
     bool mIsDefenderDisabled = false;
     int32_t mTimeToActivateSecsModified;
@@ -115,10 +116,17 @@
     int mChargeLevelStartPrevious = DEFAULT_CHARGE_LEVEL_START;
     int mChargeLevelStopPrevious = DEFAULT_CHARGE_LEVEL_STOP;
     bool mHasReachedHighCapacityLevel = false;
+    bool mWasAcOnline = false;
+    bool mWasUsbOnline = false;
 
-    void stateMachine_runAction(const state_E state);        // Process state actions
-    state_E stateMachine_getNextState(const state_E state);  // Check transitions
-    void stateMachine_firstAction(const state_E state);      // Process entry actions
+    // Process state actions
+    void stateMachine_runAction(const state_E state, struct android::BatteryProperties *props);
+
+    // Check state transitions
+    state_E stateMachine_getNextState(const state_E state);
+
+    // Process state entry actions
+    void stateMachine_firstAction(const state_E state);
 
     void clearStateData(void);
     void loadPersistentStorage(void);
@@ -130,7 +138,7 @@
     bool writeIntToFile(const char *path, const int value);
     void writeTimeToFile(const char *path, const int value, int64_t *previous);
     void writeChargeLevelsToFile(const int vendorStart, const int vendorStop);
-    bool isChargePowerAvailable(void);
+    bool isChargePowerAvailable(const bool chargerWirelessOnline);
     bool isDefaultChargeLevel(const int start, const int stop);
     bool isBatteryDefenderDisabled(const int vendorStart, const int vendorStop);
     void addTimeToChargeTimers(void);
diff --git a/health/test/TestBatteryDefender.cpp b/health/test/TestBatteryDefender.cpp
index 5edd4f4..60a30f1 100644
--- a/health/test/TestBatteryDefender.cpp
+++ b/health/test/TestBatteryDefender.cpp
@@ -104,6 +104,8 @@
 using ::testing::Return;
 using ::testing::SetArgPointee;
 
+struct android::BatteryProperties props;
+
 class BatteryDefenderTest : public ::testing::Test {
   public:
     BatteryDefenderTest() {}
@@ -111,6 +113,8 @@
     void SetUp() {
         mock = &mockFixture;
 
+        props = {};
+
         EXPECT_CALL(*mock, SetProperty(_, _)).Times(AnyNumber());
         EXPECT_CALL(*mock, ReadFileToString(_, _, _)).Times(AnyNumber());
         EXPECT_CALL(*mock, GetIntProperty(_, _, _, _)).Times(AnyNumber());
@@ -129,9 +133,7 @@
     HealthInterfaceMock mockFixture;
 };
 
-const char *kPathWirelessChargerOnline = "/sys/class/power_supply/wireless/online";
 const char *kPathWiredChargerPresent = "/sys/class/power_supply/usb/present";
-const char *kPathBatteryCapacity = "/sys/class/power_supply/battery/capacity";
 const char *kPathPersistChargerPresentTime = "/mnt/vendor/persist/battery/defender_charger_time";
 const char *kPathPersistDefenderActiveTime = "/mnt/vendor/persist/battery/defender_active_time";
 const char *kPathStartLevel = "/sys/devices/platform/soc/soc:google,charger/charge_start_level";
@@ -149,21 +151,23 @@
     ON_CALL(*mock, GetBoolProperty(kPropBatteryDefenderDisable, _)).WillByDefault(Return(false));
 }
 
-static void powerAvailable(void) {
-    ON_CALL(*mock, ReadFileToString(kPathWirelessChargerOnline, _, _))
-            .WillByDefault(DoAll(SetArgPointee<1>(std::string("1")), Return(true)));
+static void usbPresent(void) {
     ON_CALL(*mock, ReadFileToString(kPathWiredChargerPresent, _, _))
             .WillByDefault(DoAll(SetArgPointee<1>(std::string("1")), Return(true)));
 }
 
+static void powerAvailable(void) {
+    props.chargerWirelessOnline = 1;
+    usbPresent();
+}
+
 static void defaultThreshold(void) {
     ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderThreshold, _, _, _))
             .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
 }
 
 static void capacityReached(void) {
-    ON_CALL(*mock, ReadFileToString(kPathBatteryCapacity, _, _))
-            .WillByDefault(DoAll(SetArgPointee<1>(std::to_string(100)), Return(true)));
+    props.batteryLevel = 100;
 }
 
 static void initToConnectedCapacityReached(void) {
@@ -186,7 +190,7 @@
 
     // Enable Battery Defender
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISCONNECTED"));
-    battDefender.update();
+    battDefender.update(&props);
 }
 
 TEST_F(BatteryDefenderTest, DisableNonDefaultLevels) {
@@ -197,7 +201,7 @@
     EXPECT_CALL(*mock, GetIntProperty(kPropChargeLevelVendorStop, _, _, _)).WillOnce(Return(35));
 
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISABLED"));
-    battDefender.update();
+    battDefender.update(&props);
 }
 
 TEST_F(BatteryDefenderTest, DisableExplicit) {
@@ -207,7 +211,7 @@
     EXPECT_CALL(*mock, GetBoolProperty(kPropBatteryDefenderDisable, _)).WillOnce(Return(true));
 
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISABLED"));
-    battDefender.update();
+    battDefender.update(&props);
 }
 
 TEST_F(BatteryDefenderTest, InitActive) {
@@ -221,7 +225,7 @@
             .WillOnce(DoAll(SetArgPointee<1>(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1)),
                             Return(true)));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
-    battDefender.update();
+    battDefender.update(&props);
 }
 
 TEST_F(BatteryDefenderTest, InitConnectedCapacityReached) {
@@ -237,14 +241,14 @@
     EXPECT_CALL(*mock, ReadFileToString(kPathPersistChargerPresentTime, _, _))
             .WillOnce(DoAll(SetArgPointee<1>(std::to_string(time_expected)), Return(true)));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
-    battDefender.update();
+    battDefender.update(&props);
 
     testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
     time_expected = DEFAULT_TIME_TO_ACTIVATE_SECONDS - 1 + MIN_TIME_BETWEEN_FILE_UPDATES;
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(time_expected),
                                          kPathPersistChargerPresentTime, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
-    battDefender.update();
+    battDefender.update(&props);
 }
 
 TEST_F(BatteryDefenderTest, InitConnected) {
@@ -259,12 +263,12 @@
     EXPECT_CALL(*mock, ReadFileToString(kPathPersistChargerPresentTime, _, _))
             .WillOnce(DoAll(SetArgPointee<1>(std::to_string(0)), Return(true)));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
-    battDefender.update();
+    battDefender.update(&props);
 
     // mHasReachedHighCapacityLevel shall be false
     testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
-    battDefender.update();
+    battDefender.update(&props);
 }
 
 TEST_F(BatteryDefenderTest, TriggerTime) {
@@ -278,27 +282,26 @@
 
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
-    battDefender.update();
+    battDefender.update(&props);
 
     // Reached 100% capacity at least once
-    EXPECT_CALL(*mock, ReadFileToString(kPathBatteryCapacity, _, _))
-            .WillOnce(DoAll(SetArgPointee<1>(std::to_string(100)), Return(true)));
+    capacityReached();
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
-    battDefender.update();
+    battDefender.update(&props);
 
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS),
                                          kPathPersistChargerPresentTime, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS;
-    battDefender.update();
+    battDefender.update(&props);
 
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS +
                                                         MIN_TIME_BETWEEN_FILE_UPDATES),
                                          kPathPersistChargerPresentTime, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
     testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
-    battDefender.update();
+    battDefender.update(&props);
 }
 
 TEST_F(BatteryDefenderTest, ChargeLevels) {
@@ -314,13 +317,13 @@
     // No expectations needed; default values already set
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += 0;
-    battDefender.update();
+    battDefender.update(&props);
 
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(60), kPathStartLevel, _));
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(70), kPathStopLevel, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
     testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
-    battDefender.update();
+    battDefender.update(&props);
 }
 
 TEST_F(BatteryDefenderTest, ActiveTime) {
@@ -336,7 +339,7 @@
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(60), kPathStartLevel, _));
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(70), kPathStopLevel, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
-    battDefender.update();
+    battDefender.update(&props);
 }
 
 TEST_F(BatteryDefenderTest, ConnectDisconnectCycle) {
@@ -349,57 +352,262 @@
     InSequence s;
 
     // Power ON
-    ON_CALL(*mock, ReadFileToString(kPathWirelessChargerOnline, _, _))
-            .WillByDefault(DoAll(SetArgPointee<1>(std::string("1")), Return(true)));
+    props.chargerWirelessOnline = true;
 
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(1000), kPathPersistChargerPresentTime, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += 60;
-    battDefender.update();
+    battDefender.update(&props);
 
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(1060), kPathPersistChargerPresentTime, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += 60;
-    battDefender.update();
+    battDefender.update(&props);
 
     // Power OFF
-    ON_CALL(*mock, ReadFileToString(kPathWirelessChargerOnline, _, _))
-            .WillByDefault(DoAll(SetArgPointee<1>(std::string("0")), Return(true)));
+    props.chargerWirelessOnline = false;
 
     // Maintain kPathPersistChargerPresentTime = 1060
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += 60;
-    battDefender.update();
+    battDefender.update(&props);
 
     // Maintain kPathPersistChargerPresentTime = 1060
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += 60 * 4;
-    battDefender.update();
+    battDefender.update(&props);
 
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(0), kPathPersistChargerPresentTime, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISCONNECTED"));
     testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
-    battDefender.update();
+    battDefender.update(&props);
 
     // Power ON
-    ON_CALL(*mock, ReadFileToString(kPathWirelessChargerOnline, _, _))
-            .WillByDefault(DoAll(SetArgPointee<1>(std::string("1")), Return(true)));
+    props.chargerWirelessOnline = true;
 
     // Maintain kPathPersistChargerPresentTime = 0
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += 60;
-    battDefender.update();
+    battDefender.update(&props);
 
     capacityReached();
     // Maintain kPathPersistChargerPresentTime = 0
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += 60;
-    battDefender.update();
+    battDefender.update(&props);
 
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(60), kPathPersistChargerPresentTime, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
     testvar_systemTimeSecs += 60;
-    battDefender.update();
+    battDefender.update(&props);
+}
+
+TEST_F(BatteryDefenderTest, PropsOverride_InitActive_allOnlineFalse) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToActive();
+
+    InSequence s;
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = false;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, false);
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = false;
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, true);
+}
+
+TEST_F(BatteryDefenderTest, PropsOverride_InitActive_usbOnline) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToActive();
+
+    InSequence s;
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = true;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, true);
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = false;
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, true);
+}
+
+TEST_F(BatteryDefenderTest, PropsOverride_InitActive_acOnline) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToActive();
+
+    InSequence s;
+
+    props.chargerAcOnline = true;
+    props.chargerUsbOnline = false;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, true);
+    ASSERT_EQ(props.chargerUsbOnline, false);
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = false;
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, true);
+    ASSERT_EQ(props.chargerUsbOnline, false);
+}
+
+TEST_F(BatteryDefenderTest, PropsOverride_InitActive_allOnline) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToActive();
+
+    InSequence s;
+
+    props.chargerAcOnline = true;
+    props.chargerUsbOnline = true;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
+    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);
+}
+
+TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_allOnlineFalse) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToConnectedCapacityReached();
+
+    InSequence s;
+
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
+    battDefender.update(&props);
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = false;
+    testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, false);
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = false;
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, true);
+}
+
+TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_usbOnline) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToConnectedCapacityReached();
+
+    InSequence s;
+
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
+    battDefender.update(&props);
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = true;
+    testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, true);
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = false;
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, false);
+    ASSERT_EQ(props.chargerUsbOnline, true);
+}
+
+TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_acOnline) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToConnectedCapacityReached();
+
+    InSequence s;
+
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
+    battDefender.update(&props);
+
+    props.chargerAcOnline = true;
+    props.chargerUsbOnline = false;
+    testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, true);
+    ASSERT_EQ(props.chargerUsbOnline, false);
+
+    props.chargerAcOnline = false;
+    props.chargerUsbOnline = false;
+    battDefender.update(&props);
+    ASSERT_EQ(props.chargerAcOnline, true);
+    ASSERT_EQ(props.chargerUsbOnline, false);
+}
+
+TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_allOnline) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    usbPresent();
+    defaultThreshold();
+    initToConnectedCapacityReached();
+
+    InSequence s;
+
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
+    battDefender.update(&props);
+
+    props.chargerAcOnline = true;
+    props.chargerUsbOnline = true;
+    testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
+    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