From 740f348265442409fd70cd5241bcc28bfd0dba0e Mon Sep 17 00:00:00 2001 From: mxyyiyi Date: Tue, 23 Apr 2024 13:28:44 +0800 Subject: [PATCH] Remove redundant battery usage slot in database. Bug: 336423923 Test: atest SettingsRoboTests:com.android.settings.fuelgauge.batteryusage Change-Id: I1b2d172a42a20a8cc8dc734498e37ed92e4624dd --- .../fuelgauge/batteryusage/ConvertUtils.java | 13 +++++++-- .../batteryusage/DataProcessManager.java | 17 +++++++++++ .../batteryusage/bugreport/LogUtils.java | 2 ++ .../batteryusage/ConvertUtilsTest.java | 29 ++++++++++++++++++- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java index 1cbe6dae4cc..1c6ff54f818 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java +++ b/src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java @@ -321,8 +321,17 @@ public final class ConvertUtils { final List batteryEventList = new ArrayList<>(); final List levelDataList = batteryLevelData.getHourlyBatteryLevelsPerDay(); - for (BatteryLevelData.PeriodBatteryLevelData oneDayData : levelDataList) { - for (int hourIndex = 0; hourIndex < oneDayData.getLevels().size() - 1; hourIndex++) { + final int dailyDataSize = levelDataList.size(); + for (int dailyIndex = 0; dailyIndex < dailyDataSize; dailyIndex++) { + final BatteryLevelData.PeriodBatteryLevelData oneDayData = + levelDataList.get(dailyIndex); + final int hourDataSize = oneDayData.getLevels().size(); + for (int hourIndex = 0; hourIndex < hourDataSize; hourIndex++) { + // For timestamp data on adjacent days, the last data (24:00) of the previous day is + // equal to the first data (00:00) of the next day, so skip sending EVEN_HOUR event. + if (dailyIndex < dailyDataSize - 1 && hourIndex == hourDataSize - 1) { + continue; + } batteryEventList.add( convertToBatteryEvent( oneDayData.getTimestamps().get(hourIndex), diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java index afb385d59ea..719d3bd5362 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java @@ -31,6 +31,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -649,6 +650,22 @@ public class DataProcessManager { // Process raw history map data into hourly timestamps. final Map> processedBatteryHistoryMap = DataProcessor.getHistoryMapWithExpectedTimestamps(context, batteryHistoryMap); + if (isFromPeriodJob && !processedBatteryHistoryMap.isEmpty()) { + // For periodic job, only generate battery usage data between even-hour timestamps. + // Remove the timestamps: + // 1) earlier than the latest completed period job (startTimestamp) + // 2) later than current scheduled even-hour job (lastEvenHourTimestamp). + final long lastEvenHourTimestamp = TimestampUtils.getLastEvenHourTimestamp(currentTime); + final Set batteryHistMapKeySet = processedBatteryHistoryMap.keySet(); + final long minTimestamp = Collections.min(batteryHistMapKeySet); + final long maxTimestamp = Collections.max(batteryHistMapKeySet); + if (minTimestamp < startTimestamp) { + processedBatteryHistoryMap.remove(minTimestamp); + } + if (maxTimestamp > lastEvenHourTimestamp) { + processedBatteryHistoryMap.remove(maxTimestamp); + } + } // Wrap and processed history map into easy-to-use format for UI rendering. final BatteryLevelData batteryLevelData = DataProcessor.getLevelDataThroughProcessedHistoryMap( diff --git a/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java b/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java index 0ac8ccaf483..88bd4adf463 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java +++ b/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java @@ -37,6 +37,7 @@ import java.io.PrintWriter; import java.time.Clock; import java.time.Duration; import java.util.List; +import java.util.TimeZone; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -97,6 +98,7 @@ public final class LogUtils { static void dumpBatteryUsageSlotDatabaseHist(Context context, PrintWriter writer) { final BatteryUsageSlotDao dao = BatteryStateDatabase.getInstance(context).batteryUsageSlotDao(); + writer.println("\n\tBattery Usage Slot TimeZone ID: " + TimeZone.getDefault().getID()); writer.println("\n\tBattery Usage Slot DatabaseHistory:"); final List entities = dao.getAllAfterForLog(getLastFullChargeTimestamp(context)); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java index 3ed2dd1aa89..b5cb4462aec 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/ConvertUtilsTest.java @@ -565,7 +565,9 @@ public final class ConvertUtilsTest { public void convertToBatteryEventList_normalCase_returnsExpectedResult() { final BatteryLevelData batteryLevelData = new BatteryLevelData( - Map.of(1691589600000L, 98, 1691596800000L, 90, 1691596812345L, 80)); + // 2023-08-09 14:00:00 UTC + // 2023-08-09 16:00:00 UTC + Map.of(1691589600000L, 98, 1691596800000L, 90)); final List batteryEventList = ConvertUtils.convertToBatteryEventList(batteryLevelData); @@ -579,6 +581,31 @@ public final class ConvertUtilsTest { assertThat(batteryEventList.get(1).getBatteryLevel()).isEqualTo(90); } + @Test + public void convertToBatteryEventList_multipleDays_returnsExpectedResult() { + final BatteryLevelData batteryLevelData = + new BatteryLevelData( + // 2024-04-23 22:00:00 UTC + // 2024-04-24 00:00:00 UTC + // 2024-04-24 02:00:00 UTC + Map.of(1713909600000L, 98, 1713916800000L, 90, 1713924000000L, 83)); + + final List batteryEventList = + ConvertUtils.convertToBatteryEventList(batteryLevelData); + + assertThat(batteryEventList).hasSize(3); + assertThat(batteryEventList.get(0).getTimestamp()).isEqualTo(1713909600000L); + assertThat(batteryEventList.get(0).getType()).isEqualTo(BatteryEventType.EVEN_HOUR); + assertThat(batteryEventList.get(0).getBatteryLevel()).isEqualTo(98); + assertThat(batteryEventList.get(1).getTimestamp()).isEqualTo(1713916800000L); + assertThat(batteryEventList.get(1).getType()).isEqualTo(BatteryEventType.EVEN_HOUR); + assertThat(batteryEventList.get(1).getBatteryLevel()).isEqualTo(90); + assertThat(batteryEventList.get(2).getTimestamp()).isEqualTo(1713924000000L); + assertThat(batteryEventList.get(2).getType()).isEqualTo(BatteryEventType.EVEN_HOUR); + assertThat(batteryEventList.get(2).getBatteryLevel()).isEqualTo(83); + } + + @Test public void convertToBatteryUsageSlotList_normalCase_returnsExpectedResult() { BatteryDiffData batteryDiffData1 =