diff --git a/protos/fuelgauge_log.proto b/protos/fuelgauge_log.proto index e75ca48f617..36126a5b52d 100644 --- a/protos/fuelgauge_log.proto +++ b/protos/fuelgauge_log.proto @@ -43,6 +43,7 @@ message BatteryUsageHistoricalLogEntry { RECHECK_JOB = 3; FETCH_USAGE_DATA = 4; INSERT_USAGE_DATA = 5; + TIME_UPDATED = 6; } 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 ebf15433131..dc8dfb6888d 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiver.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BootBroadcastReceiver.java @@ -70,8 +70,7 @@ public final class BootBroadcastReceiver extends BroadcastReceiver { break; case Intent.ACTION_TIME_CHANGED: Log.d(TAG, "refresh job and clear all data from action=" + action); - DatabaseUtils.clearAll(context); - PeriodicJobManager.getInstance(context).refreshJob(/*fromBoot=*/ false); + DatabaseUtils.clearDataAfterTimeChangedIfNeeded(context); break; default: Log.w(TAG, "receive unsupported action=" + action); diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java index 1a226fd24ac..c298afac6bc 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java @@ -72,8 +72,6 @@ public class DataProcessManager { private static final String TAG = "DataProcessManager"; private static final List POWER_CONNECTION_EVENTS = List.of(BatteryEventType.POWER_CONNECTED, BatteryEventType.POWER_DISCONNECTED); - private static final List BATTERY_LEVEL_RECORD_EVENTS = - List.of(BatteryEventType.FULL_CHARGED, BatteryEventType.EVEN_HOUR); // For testing only. @VisibleForTesting @@ -575,7 +573,7 @@ public class DataProcessManager { final List batteryLevelRecordEvents = DatabaseUtils.getBatteryEvents( context, Calendar.getInstance(), lastFullChargeTime, - BATTERY_LEVEL_RECORD_EVENTS); + DatabaseUtils.BATTERY_LEVEL_RECORD_EVENTS); final long startTimestamp = batteryLevelRecordEvents.isEmpty() ? lastFullChargeTime : batteryLevelRecordEvents.get(0).getTimestamp(); final BatteryLevelData batteryLevelData = getPeriodBatteryLevelData(context, handler, diff --git a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java index e78d25c0191..d09984346c0 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DatabaseUtils.java @@ -53,6 +53,7 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Calendar; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.function.Function; @@ -133,6 +134,9 @@ public final class DatabaseUtils { .authority(AUTHORITY) .appendPath(BATTERY_USAGE_SLOT_TABLE) .build(); + /** A list of level record event types to access battery usage data. */ + public static final List BATTERY_LEVEL_RECORD_EVENTS = + List.of(BatteryEventType.FULL_CHARGED, BatteryEventType.EVEN_HOUR); // For testing only. @VisibleForTesting @@ -408,6 +412,35 @@ public final class DatabaseUtils { }); } + /** Clears all data and jobs if current timestamp is out of the range of last recorded job. */ + public static void clearDataAfterTimeChangedIfNeeded(Context context) { + AsyncTask.execute(() -> { + try { + final List batteryLevelRecordEvents = + DatabaseUtils.getBatteryEvents(context, Calendar.getInstance(), + getLastFullChargeTime(context), BATTERY_LEVEL_RECORD_EVENTS); + final long lastRecordTimestamp = batteryLevelRecordEvents.isEmpty() + ? INVALID_TIMESTAMP : batteryLevelRecordEvents.get(0).getTimestamp(); + final long nextRecordTimestamp = + TimestampUtils.getNextEvenHourTimestamp(lastRecordTimestamp); + final long currentTime = System.currentTimeMillis(); + final boolean isOutOfTimeRange = lastRecordTimestamp == INVALID_TIMESTAMP + || currentTime < lastRecordTimestamp || currentTime > nextRecordTimestamp; + final String logInfo = String.format(Locale.ENGLISH, + "clear database = %b, current time = %d, last record time = %d", + isOutOfTimeRange, currentTime, lastRecordTimestamp); + Log.d(TAG, logInfo); + BatteryUsageLogUtils.writeLog(context, Action.TIME_UPDATED, logInfo); + if (isOutOfTimeRange) { + DatabaseUtils.clearAll(context); + PeriodicJobManager.getInstance(context).refreshJob(/* fromBoot= */ false); + } + } catch (RuntimeException e) { + Log.e(TAG, "refreshDataAndJobIfNeededAfterTimeChanged() failed", e); + } + }); + } + /** Returns the timestamp for 00:00 6 days before the calendar date. */ public static long getTimestampSixDaysAgo(Calendar calendar) { Calendar startCalendar =