Allow the dwell defend battery defender to consume ctrl properties

Test: Ensure that the battery defender overrides its configuration
   based on the new properties. Run 'atest HealthTestCases'
Bug: 173080734
Merged-In: I7fa8cba413bbbe9b8a74e5b12c3e9687e9373b11
Change-Id: I7fa8cba413bbbe9b8a74e5b12c3e9687e9373b11
diff --git a/health/BatteryDefender.cpp b/health/BatteryDefender.cpp
index e11d1a9..37d24e5 100644
--- a/health/BatteryDefender.cpp
+++ b/health/BatteryDefender.cpp
@@ -113,8 +113,20 @@
     int chargeLevelStart = vendorStart;
     int chargeLevelStop = vendorStop;
     if (mCurrentState == STATE_ACTIVE) {
-        chargeLevelStart = kChargeLevelDefenderStart;
-        chargeLevelStop = kChargeLevelDefenderStop;
+        const int newDefenderLevelStart = android::base::GetIntProperty(
+                kPropBatteryDefenderCtrlStartSOC, kChargeLevelDefenderStart, 0, 100);
+        const int newDefenderLevelStop = android::base::GetIntProperty(
+                kPropBatteryDefenderCtrlStopSOC, kChargeLevelDefenderStop, 0, 100);
+        const bool overrideLevelsValid =
+                (newDefenderLevelStart <= newDefenderLevelStop) && (newDefenderLevelStop != 0);
+
+        if (overrideLevelsValid) {
+            chargeLevelStart = newDefenderLevelStart;
+            chargeLevelStop = newDefenderLevelStop;
+        } else {
+            chargeLevelStart = kChargeLevelDefenderStart;
+            chargeLevelStop = kChargeLevelDefenderStop;
+        }
     }
 
     // Disable battery defender effects in charger mode until
@@ -147,10 +159,12 @@
 
 bool BatteryDefender::isBatteryDefenderDisabled(const int vendorStart, const int vendorStop) {
     const bool isDefaultVendorChargeLevel = isDefaultChargeLevel(vendorStart, vendorStop);
-    const bool isExplicitlyDisabled =
+    const bool isOverrideDisabled =
             android::base::GetBoolProperty(kPropBatteryDefenderDisable, false);
+    const bool isCtrlEnabled =
+            android::base::GetBoolProperty(kPropBatteryDefenderCtrlEnable, kDefaultEnable);
 
-    return isExplicitlyDisabled || (isDefaultVendorChargeLevel == false);
+    return isOverrideDisabled || (isDefaultVendorChargeLevel == false) || (isCtrlEnabled == false);
 }
 
 void BatteryDefender::addTimeToChargeTimers(void) {
@@ -167,8 +181,20 @@
 int32_t BatteryDefender::getTimeToActivate(void) {
     // Use the default constructor value if the modified property is not between 60 and INT_MAX
     // (seconds)
-    return android::base::GetIntProperty(kPropBatteryDefenderThreshold, kTimeToActivateSecs,
-                                         (int32_t)ONE_MIN_IN_SECONDS, INT32_MAX);
+    const int32_t timeToActivateOverride =
+            android::base::GetIntProperty(kPropBatteryDefenderThreshold, kTimeToActivateSecs,
+                                          (int32_t)ONE_MIN_IN_SECONDS, INT32_MAX);
+
+    const bool overrideActive = timeToActivateOverride != kTimeToActivateSecs;
+    if (overrideActive) {
+        return timeToActivateOverride;
+    } else {
+        // No overrides taken; apply ctrl time to activate...
+        // Note; do not allow less than 1 day trigger time
+        return android::base::GetIntProperty(kPropBatteryDefenderCtrlActivateTime,
+                                             kTimeToActivateSecs, (int32_t)ONE_DAY_IN_SECONDS,
+                                             INT32_MAX);
+    }
 }
 
 void BatteryDefender::stateMachine_runAction(const state_E state,
@@ -242,12 +268,15 @@
                 }
                 FALLTHROUGH_INTENDED;
 
-            case STATE_ACTIVE:
-                if (mTimeChargerNotPresentSecs > kTimeToClearTimerSecs) {
+            case STATE_ACTIVE: {
+                const int timeToClear = android::base::GetIntProperty(
+                        kPropBatteryDefenderCtrlResumeTime, kTimeToClearTimerSecs, 0, INT32_MAX);
+
+                /* Check for mIsPowerAvailable in case timeToClear is 0 */
+                if ((mTimeChargerNotPresentSecs >= timeToClear) && (mIsPowerAvailable == false)) {
                     nextState = STATE_DISCONNECTED;
                 }
-
-                break;
+            } break;
 
             default:
                 break;
diff --git a/health/include/pixelhealth/BatteryDefender.h b/health/include/pixelhealth/BatteryDefender.h
index bc64260..d6ad0cc 100644
--- a/health/include/pixelhealth/BatteryDefender.h
+++ b/health/include/pixelhealth/BatteryDefender.h
@@ -90,8 +90,18 @@
     const char *const kPropBatteryDefenderDisable = "vendor.battery.defender.disable";
     const char *const kPropBatteryDefenderThreshold = "vendor.battery.defender.threshold";
     const char *const kPropBootmode = "ro.bootmode";
+    const char *const kPropBatteryDefenderCtrlEnable = "vendor.battery.defender.ctrl.enable";
+    const char *const kPropBatteryDefenderCtrlActivateTime =
+            "vendor.battery.defender.ctrl.trigger_time";
+    const char *const kPropBatteryDefenderCtrlResumeTime =
+            "vendor.battery.defender.ctrl.resume_time";
+    const char *const kPropBatteryDefenderCtrlStartSOC =
+            "vendor.battery.defender.ctrl.recharge_soc_start";
+    const char *const kPropBatteryDefenderCtrlStopSOC =
+            "vendor.battery.defender.ctrl.recharge_soc_stop";
 
     // Default thresholds
+    const bool kDefaultEnable = true;
     const int kChargeLevelDefaultStart = DEFAULT_CHARGE_LEVEL_START;
     const int kChargeLevelDefaultStop = DEFAULT_CHARGE_LEVEL_STOP;
     const int kChargeLevelDefenderStart = DEFAULT_CHARGE_LEVEL_DEFENDER_START;
diff --git a/health/test/TestBatteryDefender.cpp b/health/test/TestBatteryDefender.cpp
index 233dd72..1894982 100644
--- a/health/test/TestBatteryDefender.cpp
+++ b/health/test/TestBatteryDefender.cpp
@@ -145,10 +145,18 @@
 const char *kPropBatteryDefenderDisable = "vendor.battery.defender.disable";
 const char *kPropBatteryDefenderThreshold = "vendor.battery.defender.threshold";
 
+const char *kPropBatteryDefenderCtrlEnable = "vendor.battery.defender.ctrl.enable";
+const char *kPropBatteryDefenderCtrlActivateTime = "vendor.battery.defender.ctrl.trigger_time";
+const char *kPropBatteryDefenderCtrlResumeTime = "vendor.battery.defender.ctrl.resume_time";
+const char *kPropBatteryDefenderCtrlStartSOC = "vendor.battery.defender.ctrl.recharge_soc_start";
+const char *kPropBatteryDefenderCtrlStopSOC = "vendor.battery.defender.ctrl.recharge_soc_stop";
+
 static void enableDefender(void) {
     ON_CALL(*mock, GetIntProperty(kPropChargeLevelVendorStart, _, _, _)).WillByDefault(Return(0));
     ON_CALL(*mock, GetIntProperty(kPropChargeLevelVendorStop, _, _, _)).WillByDefault(Return(100));
     ON_CALL(*mock, GetBoolProperty(kPropBatteryDefenderDisable, _)).WillByDefault(Return(false));
+
+    ON_CALL(*mock, GetBoolProperty(kPropBatteryDefenderCtrlEnable, _)).WillByDefault(Return(true));
 }
 
 static void usbPresent(void) {
@@ -161,9 +169,19 @@
     usbPresent();
 }
 
-static void defaultThreshold(void) {
+static void defaultThresholds(void) {
     ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderThreshold, _, _, _))
             .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
+
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlActivateTime, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlResumeTime, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_CLEAR_SECONDS));
+
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStartSOC, _, _, _))
+            .WillByDefault(Return(70));
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStopSOC, _, _, _))
+            .WillByDefault(Return(80));
 }
 
 static void capacityReached(void) {
@@ -219,7 +237,7 @@
 
     enableDefender();
     powerAvailable();
-    defaultThreshold();
+    defaultThresholds();
 
     EXPECT_CALL(*mock, ReadFileToString(kPathPersistChargerPresentTime, _, _))
             .WillOnce(DoAll(SetArgPointee<1>(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1)),
@@ -233,7 +251,7 @@
 
     enableDefender();
     powerAvailable();
-    defaultThreshold();
+    defaultThresholds();
 
     InSequence s;
 
@@ -256,7 +274,7 @@
 
     enableDefender();
     powerAvailable();
-    defaultThreshold();
+    defaultThresholds();
 
     InSequence s;
 
@@ -276,7 +294,7 @@
 
     enableDefender();
     powerAvailable();
-    defaultThreshold();
+    defaultThresholds();
 
     InSequence s;
 
@@ -309,7 +327,7 @@
 
     enableDefender();
     powerAvailable();
-    defaultThreshold();
+    defaultThresholds();
     initToConnectedCapacityReached();
 
     InSequence s;
@@ -331,7 +349,7 @@
 
     enableDefender();
     powerAvailable();
-    defaultThreshold();
+    defaultThresholds();
     initToActive();
 
     InSequence s;
@@ -342,11 +360,65 @@
     battDefender.update(&props);
 }
 
+TEST_F(BatteryDefenderTest, ActiveTime_NonDefaultLevels) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    powerAvailable();
+    initToActive();
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderThreshold, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlActivateTime, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlResumeTime, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_CLEAR_SECONDS));
+
+    // Non-default
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStartSOC, _, _, _))
+            .WillByDefault(Return(50));
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStopSOC, _, _, _))
+            .WillByDefault(Return(60));
+
+    InSequence s;
+
+    EXPECT_CALL(*mock, WriteStringToFile(std::to_string(50), kPathStartLevel, _));
+    EXPECT_CALL(*mock, WriteStringToFile(std::to_string(60), kPathStopLevel, _));
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
+    battDefender.update(&props);
+}
+
+TEST_F(BatteryDefenderTest, ActiveTime_NonDefaultLevels_invalid) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    powerAvailable();
+    initToActive();
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderThreshold, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlActivateTime, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlResumeTime, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_CLEAR_SECONDS));
+
+    // Non-default
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStartSOC, _, _, _))
+            .WillByDefault(Return(30));
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStopSOC, _, _, _))
+            .WillByDefault(Return(10));
+
+    InSequence s;
+
+    EXPECT_CALL(*mock, WriteStringToFile(std::to_string(70), kPathStartLevel, _));
+    EXPECT_CALL(*mock, WriteStringToFile(std::to_string(80), kPathStopLevel, _));
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
+    battDefender.update(&props);
+}
+
 TEST_F(BatteryDefenderTest, ConnectDisconnectCycle) {
     BatteryDefender battDefender;
 
     enableDefender();
-    defaultThreshold();
+    defaultThresholds();
     initToConnectedCapacityReached();
 
     InSequence s;
@@ -374,9 +446,10 @@
 
     // Maintain kPathPersistChargerPresentTime = 1060
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
-    testvar_systemTimeSecs += 60 * 4;
+    testvar_systemTimeSecs += 60 * 4 - 1;
     battDefender.update(&props);
 
+    testvar_systemTimeSecs += 1;
     EXPECT_CALL(*mock, WriteStringToFile(std::to_string(0), kPathPersistChargerPresentTime, _));
     EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISCONNECTED"));
     testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
@@ -402,12 +475,50 @@
     battDefender.update(&props);
 }
 
+TEST_F(BatteryDefenderTest, ConnectDisconnectResumeTimeThreshold0) {
+    BatteryDefender battDefender;
+
+    enableDefender();
+    initToConnectedCapacityReached();
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderThreshold, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlActivateTime, _, _, _))
+            .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
+
+    // Non-default thresholds
+    ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlResumeTime, _, _, _))
+            .WillByDefault(Return(0));
+
+    InSequence s;
+
+    // Power ON
+    props.chargerWirelessOnline = true;
+
+    EXPECT_CALL(*mock, WriteStringToFile(std::to_string(1000), kPathPersistChargerPresentTime, _));
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
+    testvar_systemTimeSecs += 60;
+    battDefender.update(&props);
+
+    EXPECT_CALL(*mock, WriteStringToFile(std::to_string(1060), kPathPersistChargerPresentTime, _));
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
+    testvar_systemTimeSecs += 60;
+    battDefender.update(&props);
+
+    // Power OFF
+    props.chargerWirelessOnline = false;
+
+    EXPECT_CALL(*mock, WriteStringToFile(std::to_string(0), kPathPersistChargerPresentTime, _));
+    EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISCONNECTED"));
+    testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
+    battDefender.update(&props);
+}
+
 TEST_F(BatteryDefenderTest, PropsOverride_InitActive_allOnlineFalse) {
     BatteryDefender battDefender;
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToActive();
 
     InSequence s;
@@ -431,7 +542,7 @@
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToActive();
 
     InSequence s;
@@ -455,7 +566,7 @@
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToActive();
 
     InSequence s;
@@ -479,7 +590,7 @@
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToActive();
 
     InSequence s;
@@ -503,7 +614,7 @@
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToConnectedCapacityReached();
 
     InSequence s;
@@ -531,7 +642,7 @@
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToConnectedCapacityReached();
 
     InSequence s;
@@ -559,7 +670,7 @@
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToConnectedCapacityReached();
 
     InSequence s;
@@ -587,7 +698,7 @@
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToConnectedCapacityReached();
 
     InSequence s;
@@ -615,7 +726,7 @@
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToConnectedCapacityReached();
 
     InSequence s;
@@ -637,7 +748,7 @@
 
     enableDefender();
     usbPresent();
-    defaultThreshold();
+    defaultThresholds();
     initToConnectedCapacityReached();
 
     InSequence s;