Verify and reset invalid scheduled battery level in the booting stage

The minimum scheduled battery level is changed from 5% to 10% in T, if
users upgrade the device from S to T with invalid level value in
the Settings.Global, we have to force reset it into the new minimum
battery level value.

Bug: 258243197
Test: make RunSettingsRoboTests
Change-Id: I89003120aaebcff78d4bf3f7ae8b54e97adae3c8
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d035d5d..32b9a78 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2996,6 +2996,14 @@
         </receiver>
 
         <receiver
+            android:name=".fuelgauge.BatterySettingsMigrateChecker"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED"/>
+            </intent-filter>
+        </receiver>
+
+        <receiver
             android:name=".fuelgauge.batteryusage.PeriodicJobReceiver"
             android:exported="false">
             <intent-filter>
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java b/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java
new file mode 100644
index 0000000..e626fc3
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import android.content.ContentResolver;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleRadioButtonsController;
+
+/** Execute battery settings migration tasks in the device booting stage. */
+public final class BatterySettingsMigrateChecker extends BroadcastReceiver {
+    private static final String TAG = "BatterySettingsMigrateChecker";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        verifySaverConfiguration(context.getApplicationContext());
+    }
+
+    private static void verifySaverConfiguration(Context context) {
+        final ContentResolver resolver = context.getContentResolver();
+        final int threshold = Settings.Global.getInt(resolver,
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+        // Force refine the invalid scheduled battery level.
+        if (threshold < BatterySaverScheduleRadioButtonsController.TRIGGER_LEVEL_MIN
+                && threshold > 0) {
+            Settings.Global.putInt(resolver, Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL,
+                    BatterySaverScheduleRadioButtonsController.TRIGGER_LEVEL_MIN);
+            Log.w(TAG, "Reset invalid scheduled battery level from: " + threshold);
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
new file mode 100644
index 0000000..5117fb4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+
+import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleRadioButtonsController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public final class BatterySettingsMigrateCheckerTest {
+
+    private Context mContext;
+    private BatterySettingsMigrateChecker mBatterySettingsMigrateChecker;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mBatterySettingsMigrateChecker = new BatterySettingsMigrateChecker();
+    }
+
+    @Test
+    public void onReceive_invalidScheduledLevel_resetScheduledValue() {
+        final int invalidScheduledLevel = 5;
+        setScheduledLevel(invalidScheduledLevel);
+
+        mBatterySettingsMigrateChecker.onReceive(mContext, new Intent());
+
+        assertThat(getScheduledLevel())
+                .isEqualTo(BatterySaverScheduleRadioButtonsController.TRIGGER_LEVEL_MIN);
+    }
+
+    @Test
+    public void onReceive_validScheduledLevel_notResetScheduledValue() {
+        final int validScheduledLevel = 12;
+        setScheduledLevel(validScheduledLevel);
+
+        mBatterySettingsMigrateChecker.onReceive(mContext, new Intent());
+
+        assertThat(getScheduledLevel()).isEqualTo(validScheduledLevel);
+    }
+
+    @Test
+    public void onReceive_validSpecialScheduledLevel_notResetScheduledValue() {
+        final int validScheduledLevel = 0;
+        setScheduledLevel(validScheduledLevel);
+
+        mBatterySettingsMigrateChecker.onReceive(mContext, new Intent());
+
+        assertThat(getScheduledLevel()).isEqualTo(validScheduledLevel);
+    }
+
+    private void setScheduledLevel(int scheduledLevel) {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, scheduledLevel);
+    }
+
+    private int getScheduledLevel() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, /*defaultValue*/ 0);
+    }
+}