From 56aa92f7c41b416f75c83e2b388c775ca71f546b Mon Sep 17 00:00:00 2001 From: mxyyiyi Date: Mon, 6 Nov 2023 17:09:45 +0800 Subject: [PATCH] Add log of BatteryEvent and BatteryUsageSlot while dumpping. Test: manual Bug: 294945588 Change-Id: If3cb4a4014d20f0d0c6275f54d141c1bdb4ac962 --- .../bugreport/BugReportContentProvider.java | 10 ++- .../batteryusage/bugreport/LogUtils.java | 72 +++++++++++++++++-- .../batteryusage/db/BatteryEventDao.java | 12 ++++ .../batteryusage/db/BatteryUsageSlotDao.java | 6 ++ 4 files changed, 92 insertions(+), 8 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProvider.java b/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProvider.java index 60d73142b61..7dc7700b001 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProvider.java +++ b/src/com/android/settings/fuelgauge/batteryusage/bugreport/BugReportContentProvider.java @@ -39,11 +39,16 @@ public final class BugReportContentProvider extends ContentProvider { @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { - final Context context = getContext(); + Context context = getContext(); if (context == null) { Log.w(TAG, "failed to dump BatteryUsage state: null context"); return; } + context = context.getApplicationContext(); + if (context == null) { + Log.w(TAG, "failed to dump BatteryUsage state: null application context"); + return; + } if (DatabaseUtils.isWorkProfile(context)) { Log.w(TAG, "ignore battery usage states dump in the work profile"); return; @@ -51,6 +56,9 @@ public final class BugReportContentProvider extends ContentProvider { writer.println("dump BatteryUsage and AppUsage states:"); LogUtils.dumpBatteryUsageDatabaseHist(context, writer); LogUtils.dumpAppUsageDatabaseHist(context, writer); + LogUtils.dumpBatteryUsageSlotDatabaseHist(context, writer); + LogUtils.dumpBatteryEventDatabaseHist(context, writer); + LogUtils.dumpBatteryStateDatabaseHist(context, writer); } @Override diff --git a/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java b/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java index b461d20a1da..0ac8ccaf483 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java +++ b/src/com/android/settings/fuelgauge/batteryusage/bugreport/LogUtils.java @@ -19,18 +19,26 @@ package com.android.settings.fuelgauge.batteryusage.bugreport; import android.content.Context; import android.util.Log; +import com.android.settings.fuelgauge.BatteryUtils; +import com.android.settings.fuelgauge.batteryusage.BatteryUsageSlot; import com.android.settings.fuelgauge.batteryusage.ConvertUtils; import com.android.settings.fuelgauge.batteryusage.DatabaseUtils; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventDao; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity; +import com.android.settings.fuelgauge.batteryusage.db.BatteryEventDao; +import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity; import com.android.settings.fuelgauge.batteryusage.db.BatteryState; import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao; import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase; +import com.android.settings.fuelgauge.batteryusage.db.BatteryUsageSlotDao; +import com.android.settings.fuelgauge.batteryusage.db.BatteryUsageSlotEntity; import java.io.PrintWriter; import java.time.Clock; import java.time.Duration; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; /** A utility class to aggregate and provide required log data. */ public final class LogUtils { @@ -47,8 +55,7 @@ public final class LogUtils { // Dumps phenotype environments. DatabaseUtils.dump(context, writer); writer.flush(); - final BatteryStateDao dao = - BatteryStateDatabase.getInstance(context.getApplicationContext()).batteryStateDao(); + final BatteryStateDao dao = BatteryStateDatabase.getInstance(context).batteryStateDao(); final long timeOffset = Clock.systemUTC().millis() - DUMP_TIME_OFFSET.toMillis(); // Gets all distinct timestamps. @@ -69,22 +76,73 @@ public final class LogUtils { Log.w(TAG, "\t" + formattedTimestamp); }); writer.flush(); + } + static void dumpBatteryStateDatabaseHist(Context context, PrintWriter writer) { + final BatteryStateDao dao = BatteryStateDatabase.getInstance(context).batteryStateDao(); + writer.println("\n\tBatteryState DatabaseHistory:"); final List stateList = dao.getAllAfter(Clock.systemUTC().millis() - DUMP_TIME_OFFSET_FOR_ENTRY.toMillis()); - stateList.stream().forEach(state -> writer.println(state)); + dumpListItems(writer, stateList, state -> state); } static void dumpAppUsageDatabaseHist(Context context, PrintWriter writer) { - final AppUsageEventDao dao = - BatteryStateDatabase.getInstance(context.getApplicationContext()) - .appUsageEventDao(); + final AppUsageEventDao dao = BatteryStateDatabase.getInstance(context).appUsageEventDao(); writer.println("\n\tApp DatabaseHistory:"); final List eventList = dao.getAllAfter(Clock.systemUTC().millis() - DUMP_TIME_OFFSET_FOR_ENTRY.toMillis()); - eventList.stream().forEach(event -> writer.println(event)); + dumpListItems(writer, eventList, event -> event); + } + + static void dumpBatteryUsageSlotDatabaseHist(Context context, PrintWriter writer) { + final BatteryUsageSlotDao dao = + BatteryStateDatabase.getInstance(context).batteryUsageSlotDao(); + writer.println("\n\tBattery Usage Slot DatabaseHistory:"); + final List entities = + dao.getAllAfterForLog(getLastFullChargeTimestamp(context)); + dumpListItems( + writer, + entities, + entity -> + BatteryUtils.parseProtoFromString( + entity.batteryUsageSlot, BatteryUsageSlot.getDefaultInstance())); + } + + static void dumpBatteryEventDatabaseHist(Context context, PrintWriter writer) { + final BatteryEventDao dao = BatteryStateDatabase.getInstance(context).batteryEventDao(); + writer.println("\n\tBattery Event DatabaseHistory:"); + final List entities = + dao.getAllAfterForLog(getLastFullChargeTimestamp(context)); + dumpListItems(writer, entities, entity -> entity); + } + + private static void dumpListItems( + PrintWriter writer, List itemList, Function itemConverter) { + final AtomicInteger counter = new AtomicInteger(0); + try { + itemList.forEach( + item -> { + writer.println(itemConverter.apply(item)); + if (counter.incrementAndGet() % 20 == 0) { + writer.flush(); + } + }); + } catch (RuntimeException e) { + Log.e(TAG, "dumpListItems() error: ", e); + } writer.flush(); } + private static long getLastFullChargeTimestamp(Context context) { + final BatteryEventDao dao = BatteryStateDatabase.getInstance(context).batteryEventDao(); + try { + final Long lastFullChargeTimestamp = dao.getLastFullChargeTimestampForLog(); + return lastFullChargeTimestamp != null ? lastFullChargeTimestamp : 0L; + } catch (RuntimeException e) { + Log.e(TAG, "getLastFullChargeTimestamp() error: ", e); + return 0L; + } + } + private LogUtils() {} } diff --git a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDao.java b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDao.java index f1b2d66f17d..8b696fe96c0 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDao.java +++ b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryEventDao.java @@ -42,6 +42,12 @@ public interface BatteryEventDao { + " WHERE batteryEventType = 3") // BatteryEventType.FULL_CHARGED = 3 Cursor getLastFullChargeTimestamp(); + /** Gets the {@link Long} of the last full charge time . */ + @Query( + "SELECT MAX(timestamp) FROM BatteryEventEntity" + + " WHERE batteryEventType = 3") // BatteryEventType.FULL_CHARGED = 3 + Long getLastFullChargeTimestampForLog(); + /** Gets the {@link Cursor} of all recorded data after a specific timestamp. */ @Query( "SELECT * FROM BatteryEventEntity" @@ -49,6 +55,12 @@ public interface BatteryEventDao { + " ORDER BY timestamp DESC") Cursor getAllAfter(long timestamp, List batteryEventTypes); + /** Gets all recorded data after a specific timestamp for log.*/ + @Query( + "SELECT * FROM BatteryEventEntity " + + "WHERE timestamp >= :timestamp ORDER BY timestamp DESC") + List getAllAfterForLog(long timestamp); + /** Deletes all recorded data before a specific timestamp. */ @Query("DELETE FROM BatteryEventEntity WHERE timestamp <= :timestamp") void clearAllBefore(long timestamp); diff --git a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryUsageSlotDao.java b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryUsageSlotDao.java index b1900c7d7a6..d8cf41d0ce8 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryUsageSlotDao.java +++ b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryUsageSlotDao.java @@ -42,6 +42,12 @@ public interface BatteryUsageSlotDao { + " ORDER BY timestamp ASC") Cursor getAllAfter(long timestamp); + /** Gets all recorded data after a specific timestamp for log.*/ + @Query( + "SELECT * FROM BatteryUsageSlotEntity WHERE timestamp >= :timestamp" + + " ORDER BY timestamp DESC") + List getAllAfterForLog(long timestamp); + /** Deletes all recorded data before a specific timestamp. */ @Query("DELETE FROM BatteryUsageSlotEntity WHERE timestamp <= :timestamp") void clearAllBefore(long timestamp);