From 5ee2f6caac1218c05c4eab9a093825f3f27b0cfc Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Thu, 3 Jun 2021 12:10:54 -0700 Subject: [PATCH] Implement battery_usage_stats_before_reset pull atom Bug: 187223764 Test: m statsd_testdrive; statsd_testdrive 10111 Change-Id: I3c27deb57672d962f1029219b50d21d784c997b7 Merged-In: I3c27deb57672d962f1029219b50d21d784c997b7 (cherry picked from commit 0d25efa419034e7ac06edab9729f55f6b1ffe8ac) --- .../internal/os/BatteryUsageStatsStore.java | 54 +++++++++++++++++++ .../os/BatteryUsageStatsStoreTest.java | 10 ++++ .../server/am/BatteryStatsService.java | 32 ++++++++--- 3 files changed, 88 insertions(+), 8 deletions(-) diff --git a/core/java/com/android/internal/os/BatteryUsageStatsStore.java b/core/java/com/android/internal/os/BatteryUsageStatsStore.java index 32cd958b012c9..5c976025d39dd 100644 --- a/core/java/com/android/internal/os/BatteryUsageStatsStore.java +++ b/core/java/com/android/internal/os/BatteryUsageStatsStore.java @@ -21,6 +21,7 @@ import android.content.Context; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Handler; +import android.util.AtomicFile; import android.util.LongArray; import android.util.Slog; import android.util.TypedXmlPullParser; @@ -44,6 +45,7 @@ import java.nio.file.StandardOpenOption; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Properties; import java.util.TreeMap; /** @@ -60,12 +62,16 @@ public class BatteryUsageStatsStore { private static final String BATTERY_USAGE_STATS_DIR = "battery-usage-stats"; private static final String SNAPSHOT_FILE_EXTENSION = ".bus"; private static final String DIR_LOCK_FILENAME = ".lock"; + private static final String CONFIG_FILENAME = "config"; + private static final String BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP_PROPERTY = + "BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP"; private static final long MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES = 100 * 1024; private final Context mContext; private final BatteryStatsImpl mBatteryStats; private final File mStoreDir; private final File mLockFile; + private final AtomicFile mConfigFile; private final long mMaxStorageBytes; private final Handler mHandler; private final BatteryUsageStatsProvider mBatteryUsageStatsProvider; @@ -82,6 +88,7 @@ public class BatteryUsageStatsStore { mBatteryStats = batteryStats; mStoreDir = new File(systemDir, BATTERY_USAGE_STATS_DIR); mLockFile = new File(mStoreDir, DIR_LOCK_FILENAME); + mConfigFile = new AtomicFile(new File(mStoreDir, CONFIG_FILENAME)); mHandler = handler; mMaxStorageBytes = maxStorageBytes; mBatteryStats.setBatteryResetListener(this::prepareForBatteryStatsReset); @@ -166,6 +173,53 @@ public class BatteryUsageStatsStore { return null; } + /** + * Saves the supplied timestamp of the BATTERY_USAGE_STATS_BEFORE_RESET statsd atom pull + * in persistent file. + */ + public void setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(long timestamp) { + Properties props = new Properties(); + try (FileLock lock = lockSnapshotDirectory()) { + try (InputStream in = mConfigFile.openRead()) { + props.load(in); + } catch (IOException e) { + Slog.e(TAG, "Cannot load config file " + mConfigFile, e); + } + props.put(BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP_PROPERTY, + String.valueOf(timestamp)); + FileOutputStream out = null; + try { + out = mConfigFile.startWrite(); + props.store(out, "Statsd atom pull timestamps"); + mConfigFile.finishWrite(out); + } catch (IOException e) { + mConfigFile.failWrite(out); + Slog.e(TAG, "Cannot save config file " + mConfigFile, e); + } + } catch (IOException e) { + Slog.e(TAG, "Cannot lock battery usage stats directory", e); + } + } + + /** + * Retrieves the previously saved timestamp of the last BATTERY_USAGE_STATS_BEFORE_RESET + * statsd atom pull. + */ + public long getLastBatteryUsageStatsBeforeResetAtomPullTimestamp() { + Properties props = new Properties(); + try (FileLock lock = lockSnapshotDirectory()) { + try (InputStream in = mConfigFile.openRead()) { + props.load(in); + } catch (IOException e) { + Slog.e(TAG, "Cannot load config file " + mConfigFile, e); + } + } catch (IOException e) { + Slog.e(TAG, "Cannot lock battery usage stats directory", e); + } + return Long.parseLong( + props.getProperty(BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP_PROPERTY, "0")); + } + private FileLock lockSnapshotDirectory() throws IOException { mLockFile.getParentFile().mkdirs(); mLockFile.createNewFile(); diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java index 9b9c8e3fa5c1d..141a9fa30c850 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java @@ -122,6 +122,16 @@ public class BatteryUsageStatsStoreTest { .isAtMost(MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES); } + @Test + public void testSavingStatsdAtomPullTimestamp() { + mBatteryUsageStatsStore.setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(1234); + assertThat(mBatteryUsageStatsStore.getLastBatteryUsageStatsBeforeResetAtomPullTimestamp()) + .isEqualTo(1234); + mBatteryUsageStatsStore.setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(5478); + assertThat(mBatteryUsageStatsStore.getLastBatteryUsageStatsBeforeResetAtomPullTimestamp()) + .isEqualTo(5478); + } + private void prepareBatteryStats() { mBatteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100, /* plugType */ 0, 90, 72, 3700, 3_600_000, 4_000_000, 0, diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 94106bc3e1990..7f6e6687625c5 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -125,7 +125,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub Watchdog.Monitor { static final String TAG = "BatteryStatsService"; static final boolean DBG = false; - private static final boolean BATTERY_USAGE_STORE_ENABLED = false; + private static final boolean BATTERY_USAGE_STORE_ENABLED = true; private static IBatteryStats sService; @@ -344,12 +344,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub mStats = new BatteryStatsImpl(systemDir, handler, this, this, mUserManagerUserInfoProvider); - if (BATTERY_USAGE_STORE_ENABLED) { - mBatteryUsageStatsStore = - new BatteryUsageStatsStore(context, mStats, systemDir, mHandler); - } else { - mBatteryUsageStatsStore = null; - } mWorker = new BatteryExternalStatsWorker(context, mStats); mStats.setExternalStatsSyncLocked(mWorker); mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger( @@ -357,7 +351,14 @@ public final class BatteryStatsService extends IBatteryStats.Stub mStats.setPowerProfileLocked(new PowerProfile(context)); mStats.startTrackingSystemServerCpuTime(); - mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mStats); + if (BATTERY_USAGE_STORE_ENABLED) { + mBatteryUsageStatsStore = + new BatteryUsageStatsStore(context, mStats, systemDir, mHandler); + } else { + mBatteryUsageStatsStore = null; + } + mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mStats, + mBatteryUsageStatsStore); } public void publish() { @@ -761,6 +762,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL, null, // use default PullAtomMetadata values BackgroundThread.getExecutor(), pullAtomCallback); + statsManager.setPullAtomCallback( + FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET, + null, // use default PullAtomMetadata values + BackgroundThread.getExecutor(), pullAtomCallback); } /** StatsPullAtomCallback for pulling BatteryUsageStats data. */ @@ -777,6 +782,17 @@ public final class BatteryStatsService extends IBatteryStats.Stub new BatteryUsageStatsQuery.Builder().powerProfileModeledOnly().build(); bus = getBatteryUsageStats(List.of(powerProfileQuery)).get(0); break; + case FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET: + final long sessionStart = mBatteryUsageStatsStore + .getLastBatteryUsageStatsBeforeResetAtomPullTimestamp(); + final long sessionEnd = mStats.getStartClockTime(); + final BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder() + .aggregateSnapshots(sessionStart, sessionEnd) + .build(); + bus = getBatteryUsageStats(List.of(query)).get(0); + mBatteryUsageStatsStore + .setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(sessionEnd); + break; default: throw new UnsupportedOperationException("Unknown tagId=" + atomTag); }