diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ad815516c61..e085be86407 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3343,6 +3343,7 @@
+
diff --git a/protos/fuelgauge_log.proto b/protos/fuelgauge_log.proto
index 4bee75ca058..b16958d8e2b 100644
--- a/protos/fuelgauge_log.proto
+++ b/protos/fuelgauge_log.proto
@@ -45,6 +45,7 @@ message BatteryUsageHistoricalLogEntry {
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 5fa04eb0959..b758df4bd6b 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiver.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiver.java
@@ -70,6 +70,10 @@ public final class BootBroadcastReceiver extends BroadcastReceiver {
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 b40f71ac16e..5b28abb422f 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.List;
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 @@ public final class DatabaseUtils {
});
}
+ /** 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 @@ public final class DatabaseUtils {
}
}
+ 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 3e53b036edd..545f7733f41 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiverTest.java
@@ -173,6 +173,20 @@ public final class BootBroadcastReceiverTest {
assertThat(mShadowAlarmManager.peekNextScheduledAlarm()).isNull();
}
+ @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);