Update database clear & job refresh mechanism for time zone change intent

- Clear database and reset periodic job
- Take a snapshot of current battery usage stats

Bug: 336423923
Test: atest SettingsRoboTests:com.android.settings.fuelgauge.batteryusage
Change-Id: I4aade9db950b508e2190605371f246904f131da3
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ad81551..e085be8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3343,6 +3343,7 @@
                 <action android:name="com.google.android.setupwizard.SETUP_WIZARD_FINISHED"/>
                 <action android:name="com.android.settings.battery.action.PERIODIC_JOB_RECHECK"/>
                 <action android:name="android.intent.action.TIME_SET"/>
+                <action android:name="android.intent.action.TIMEZONE_CHANGED"/>
             </intent-filter>
         </receiver>
 
diff --git a/protos/fuelgauge_log.proto b/protos/fuelgauge_log.proto
index 4bee75c..b16958d 100644
--- a/protos/fuelgauge_log.proto
+++ b/protos/fuelgauge_log.proto
@@ -45,6 +45,7 @@
     FETCH_USAGE_DATA = 4;
     INSERT_USAGE_DATA = 5;
     TIME_UPDATED = 6;
+    TIMEZONE_UPDATED = 7;
   }
 
   optional int64 timestamp = 1;
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiver.java b/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiver.java
index 5fa04eb..b758df4 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiver.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiver.java
@@ -70,6 +70,10 @@
                 Log.d(TAG, "refresh job and clear data from action=" + action);
                 DatabaseUtils.clearDataAfterTimeChangedIfNeeded(context, intent);
                 break;
+            case Intent.ACTION_TIMEZONE_CHANGED:
+                Log.d(TAG, "refresh job and clear all data from action=" + action);
+                DatabaseUtils.clearDataAfterTimeZoneChangedIfNeeded(context);
+                break;
             default:
                 Log.w(TAG, "receive unsupported action=" + action);
         }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
index b40f71a..5b28abb 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java
@@ -57,6 +57,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.TimeZone;
 import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
@@ -495,6 +496,22 @@
                 });
     }
 
+    /** Clears all data and reset jobs if timezone changed. */
+    public static void clearDataAfterTimeZoneChangedIfNeeded(Context context) {
+        AsyncTask.execute(
+                () -> {
+                    try {
+                        clearDataAfterTimeZoneChangedIfNeededInternal(context);
+                    } catch (RuntimeException e) {
+                        Log.e(TAG, "clearDataAfterTimeZoneChangedIfNeeded() failed", e);
+                        BatteryUsageLogUtils.writeLog(
+                                context,
+                                Action.TIMEZONE_UPDATED,
+                                "clearDataAfterTimeZoneChangedIfNeeded() failed" + e);
+                    }
+                });
+    }
+
     /** Returns the timestamp for 00:00 6 days before the calendar date. */
     public static long getTimestampSixDaysAgo(Calendar calendar) {
         Calendar startCalendar =
@@ -896,6 +913,20 @@
         }
     }
 
+    private static void clearDataAfterTimeZoneChangedIfNeededInternal(Context context) {
+        final String logInfo =
+                String.format(
+                        Locale.ENGLISH,
+                        "clear database for new time zone = %s",
+                        TimeZone.getDefault().toString());
+        BatteryUsageLogUtils.writeLog(context, Action.TIMEZONE_UPDATED, logInfo);
+        Log.d(TAG, logInfo);
+        DatabaseUtils.clearAll(context);
+        PeriodicJobManager.getInstance(context).refreshJob(/* fromBoot= */ false);
+        // Take a snapshot of battery usage data immediately
+        BatteryUsageDataLoader.enqueueWork(context, /* isFullChargeStart= */ true);
+    }
+
     private static long loadLongFromContentProvider(
             Context context, Uri uri, final long defaultValue) {
         return loadFromContentProvider(
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiverTest.java
index 3e53b03..545f773 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiverTest.java
@@ -174,6 +174,20 @@
     }
 
     @Test
+    public void onReceive_withTimeZoneChangedIntent_clearAllDataAndRefreshesJob()
+            throws InterruptedException {
+        BatteryTestUtils.insertDataToBatteryStateTable(
+                mContext, Clock.systemUTC().millis(), "com.android.systemui");
+        assertThat(mDao.getAllAfter(0).size()).isEqualTo(1);
+
+        mReceiver.onReceive(mContext, new Intent(Intent.ACTION_TIMEZONE_CHANGED));
+
+        TimeUnit.MILLISECONDS.sleep(100);
+        assertThat(mDao.getAllAfter(0)).isEmpty();
+        assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNotNull();
+    }
+
+    @Test
     public void invokeJobRecheck_broadcastsIntent() {
         BootBroadcastReceiver.invokeJobRecheck(mContext);