Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ee2f6ca authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

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 0d25efa4)
parent c24fb816
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -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();
+10 −0
Original line number Diff line number Diff line
@@ -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,
+24 −8
Original line number Diff line number Diff line
@@ -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);
            }