Fix battery usage chart was unexpectedly cleared

Bug: 318308397
Fix: 318308397
Test: manual
Change-Id: Ia00c0680a563eaffb3609c1372336a6b9ed7fa17
This commit is contained in:
Zaiyue Xue
2024-01-02 11:55:02 +08:00
parent a579912892
commit 9c06e522bc
2 changed files with 56 additions and 27 deletions

View File

@@ -71,7 +71,7 @@ public final class BootBroadcastReceiver extends BroadcastReceiver {
break; break;
case Intent.ACTION_TIME_CHANGED: case Intent.ACTION_TIME_CHANGED:
Log.d(TAG, "refresh job and clear all data from action=" + action); Log.d(TAG, "refresh job and clear all data from action=" + action);
DatabaseUtils.clearDataAfterTimeChangedIfNeeded(context); DatabaseUtils.clearDataAfterTimeChangedIfNeeded(context, intent);
break; break;
default: default:
Log.w(TAG, "receive unsupported action=" + action); Log.w(TAG, "receive unsupported action=" + action);

View File

@@ -16,6 +16,8 @@
package com.android.settings.fuelgauge.batteryusage; package com.android.settings.fuelgauge.batteryusage;
import static android.content.Intent.FLAG_RECEIVER_REPLACE_PENDING;
import static com.android.settings.fuelgauge.batteryusage.ConvertUtils.utcToLocalTimeForLogging; import static com.android.settings.fuelgauge.batteryusage.ConvertUtils.utcToLocalTimeForLogging;
import android.app.usage.IUsageStatsManager; import android.app.usage.IUsageStatsManager;
@@ -150,6 +152,7 @@ public final class DatabaseUtils {
.authority(AUTHORITY) .authority(AUTHORITY)
.appendPath(BATTERY_USAGE_SLOT_TABLE) .appendPath(BATTERY_USAGE_SLOT_TABLE)
.build(); .build();
/** A list of level record event types to access battery usage data. */ /** A list of level record event types to access battery usage data. */
public static final List<BatteryEventType> BATTERY_LEVEL_RECORD_EVENTS = public static final List<BatteryEventType> BATTERY_LEVEL_RECORD_EVENTS =
List.of(BatteryEventType.FULL_CHARGED, BatteryEventType.EVEN_HOUR); List.of(BatteryEventType.FULL_CHARGED, BatteryEventType.EVEN_HOUR);
@@ -454,32 +457,58 @@ public final class DatabaseUtils {
} }
/** Clears all data and jobs if current timestamp is out of the range of last recorded job. */ /** Clears all data and jobs if current timestamp is out of the range of last recorded job. */
public static void clearDataAfterTimeChangedIfNeeded(Context context) { public static void clearDataAfterTimeChangedIfNeeded(Context context, Intent intent) {
AsyncTask.execute(() -> { AsyncTask.execute(
try { () -> {
final List<BatteryEvent> batteryLevelRecordEvents = try {
DatabaseUtils.getBatteryEvents(context, Calendar.getInstance(), if ((intent.getFlags() & FLAG_RECEIVER_REPLACE_PENDING) != 0) {
getLastFullChargeTime(context), BATTERY_LEVEL_RECORD_EVENTS); BatteryUsageLogUtils.writeLog(
final long lastRecordTimestamp = batteryLevelRecordEvents.isEmpty() context,
? INVALID_TIMESTAMP : batteryLevelRecordEvents.get(0).getTimestamp(); Action.TIME_UPDATED,
final long nextRecordTimestamp = "Database is not cleared because the time change intent is only"
TimestampUtils.getNextEvenHourTimestamp(lastRecordTimestamp); + " for the existing pending receiver.");
final long currentTime = System.currentTimeMillis(); return;
final boolean isOutOfTimeRange = lastRecordTimestamp == INVALID_TIMESTAMP }
|| currentTime < lastRecordTimestamp || currentTime > nextRecordTimestamp; final List<BatteryEvent> batteryLevelRecordEvents =
final String logInfo = String.format(Locale.ENGLISH, DatabaseUtils.getBatteryEvents(
"clear database = %b, current time = %d, last record time = %d", context,
isOutOfTimeRange, currentTime, lastRecordTimestamp); Calendar.getInstance(),
Log.d(TAG, logInfo); getLastFullChargeTime(context),
BatteryUsageLogUtils.writeLog(context, Action.TIME_UPDATED, logInfo); BATTERY_LEVEL_RECORD_EVENTS);
if (isOutOfTimeRange) { final long lastRecordTimestamp =
DatabaseUtils.clearAll(context); batteryLevelRecordEvents.isEmpty()
PeriodicJobManager.getInstance(context).refreshJob(/* fromBoot= */ false); ? INVALID_TIMESTAMP
} : batteryLevelRecordEvents.get(0).getTimestamp();
} catch (RuntimeException e) { final long nextRecordTimestamp =
Log.e(TAG, "refreshDataAndJobIfNeededAfterTimeChanged() failed", e); 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);
BatteryUsageLogUtils.writeLog(
context,
Action.TIME_UPDATED,
"refreshDataAndJobIfNeededAfterTimeChanged() failed" + e);
}
});
} }
/** Returns the timestamp for 00:00 6 days before the calendar date. */ /** Returns the timestamp for 00:00 6 days before the calendar date. */