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

Commit f96d78f4 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Consistently close BatteryUsageStats objects" into main

parents 8ae058d1 9835370d
Loading
Loading
Loading
Loading
+61 −1
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import android.util.Range;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BatteryStatsHistory;
import com.android.internal.os.BatteryStatsHistoryIterator;
import com.android.internal.os.MonotonicClock;
@@ -43,7 +45,9 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Contains a snapshot of battery attribution data, on a per-subsystem and per-UID basis.
@@ -126,6 +130,12 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
    // Max window size. CursorWindow uses only as much memory as needed.
    private static final long BATTERY_CONSUMER_CURSOR_WINDOW_SIZE = 20_000_000; // bytes

    /**
     * Used by tests to ensure all BatteryUsageStats instances are closed.
     */
    @VisibleForTesting
    public static boolean DEBUG_INSTANCE_COUNT;

    private static final int STATSD_PULL_ATOM_MAX_BYTES = 45000;

    private static final int[] UID_USAGE_TIME_PROCESS_STATES = {
@@ -153,7 +163,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
    private final List<UserBatteryConsumer> mUserBatteryConsumers;
    private final AggregateBatteryConsumer[] mAggregateBatteryConsumers;
    private final BatteryStatsHistory mBatteryStatsHistory;
    private BatteryConsumer.BatteryConsumerDataLayout mBatteryConsumerDataLayout;
    private final BatteryConsumer.BatteryConsumerDataLayout mBatteryConsumerDataLayout;
    private CursorWindow mBatteryConsumersCursorWindow;

    private BatteryUsageStats(@NonNull Builder builder) {
@@ -873,6 +883,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {

    @Override
    public void close() throws IOException {
        onCursorWindowReleased(mBatteryConsumersCursorWindow);
        mBatteryConsumersCursorWindow.close();
        mBatteryConsumersCursorWindow = null;
    }
@@ -880,6 +891,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
    @Override
    protected void finalize() throws Throwable {
        if (mBatteryConsumersCursorWindow != null) {
            // Do not decrement sOpenCusorWindowCount. All instances should be closed explicitly
            mBatteryConsumersCursorWindow.close();
        }
        super.finalize();
@@ -934,6 +946,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
                boolean includesPowerStateData, double minConsumedPowerThreshold) {
            mBatteryConsumersCursorWindow =
                    new CursorWindow(null, BATTERY_CONSUMER_CURSOR_WINDOW_SIZE);
            onCursorWindowAllocated(mBatteryConsumersCursorWindow);
            mBatteryConsumerDataLayout = BatteryConsumer.createBatteryConsumerDataLayout(
                    customPowerComponentNames, includePowerModels, includeProcessStateData,
                    includeScreenStateData, includesPowerStateData);
@@ -996,6 +1009,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
         */
        public void discard() {
            mBatteryConsumersCursorWindow.close();
            onCursorWindowReleased(mBatteryConsumersCursorWindow);
        }

        /**
@@ -1264,4 +1278,50 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
            }
        }
    }

    @GuardedBy("BatteryUsageStats.class")
    private static Map<CursorWindow, Exception> sInstances;

    private static void onCursorWindowAllocated(CursorWindow window) {
        if (!DEBUG_INSTANCE_COUNT) {
            return;
        }

        synchronized (BatteryUsageStats.class) {
            if (sInstances == null) {
                sInstances = new HashMap<>();
            }
            sInstances.put(window, new Exception());
        }
    }

    private static void onCursorWindowReleased(CursorWindow window) {
        if (!DEBUG_INSTANCE_COUNT) {
            return;
        }

        synchronized (BatteryUsageStats.class) {
            sInstances.remove(window);
        }
    }

    /**
     * Used by tests to ensure all BatteryUsageStats instances are closed.
     */
    @VisibleForTesting
    public static void assertAllInstancesClosed() {
        if (!DEBUG_INSTANCE_COUNT) {
            throw new IllegalStateException("DEBUG_INSTANCE_COUNT is false");
        }

        synchronized (BatteryUsageStats.class) {
            if (!sInstances.isEmpty()) {
                Exception callSite = sInstances.entrySet().iterator().next().getValue();
                int count = sInstances.size();
                sInstances.clear();
                throw new IllegalStateException(
                        "Instances of BatteryUsageStats not closed: " + count, callSite);
            }
        }
    }
}
+9 −6
Original line number Diff line number Diff line
@@ -3178,13 +3178,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub
            mStats.collectPowerStatsSamples();
        }

        BatteryUsageStats batteryUsageStats =
                mBatteryUsageStatsProvider.getBatteryUsageStats(mStats, query);
        try (BatteryUsageStats batteryUsageStats =
                     mBatteryUsageStatsProvider.getBatteryUsageStats(mStats, query)) {
            if (proto) {
                batteryUsageStats.dumpToProto(fd);
            } else {
                batteryUsageStats.dump(pw, "  ");
            }
        } catch (IOException e) {
            Slog.e(TAG, "Cannot close BatteryUsageStats", e);
        }
    }

    private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
+5 −0
Original line number Diff line number Diff line
@@ -51,6 +51,11 @@ class AccumulatedBatteryUsageStatsSection extends PowerStatsSpan.Section {
        mBatteryUsageStats.build().dump(ipw, "");
    }

    @Override
    public void close() {
        mBatteryUsageStats.discard();
    }

    static class Reader implements PowerStatsSpan.SectionReader {
        @Override
        public String getType() {
+22 −20
Original line number Diff line number Diff line
@@ -295,7 +295,8 @@ public class BatteryUsageStatsProvider {
                    stats.builder = ((AccumulatedBatteryUsageStatsSection) section)
                            .getBatteryUsageStatsBuilder();
                    stats.startWallClockTime = powerStatsSpan.getMetadata().getStartTime();
                    stats.startMonotonicTime = powerStatsSpan.getMetadata().getStartMonotonicTime();
                    stats.startMonotonicTime =
                            powerStatsSpan.getMetadata().getStartMonotonicTime();
                    stats.endMonotonicTime = powerStatsSpan.getMetadata().getEndMonotonicTime();
                    break;
                }
@@ -484,8 +485,8 @@ public class BatteryUsageStatsProvider {
                continue;
            }

            PowerStatsSpan powerStatsSpan = mPowerStatsStore.loadPowerStatsSpan(
                    spanMetadata.getId(), BatteryUsageStatsSection.TYPE);
            try (PowerStatsSpan powerStatsSpan = mPowerStatsStore.loadPowerStatsSpan(
                    spanMetadata.getId(), BatteryUsageStatsSection.TYPE)) {
                if (powerStatsSpan == null) {
                    continue;
                }
@@ -509,6 +510,7 @@ public class BatteryUsageStatsProvider {
                    builder.add(snapshot);
                }
            }
        }
        return builder.build();
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.power.stats;

import android.os.BatteryUsageStats;
import android.util.IndentingPrintWriter;
import android.util.Slog;

import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -28,6 +29,7 @@ import java.io.IOException;

class BatteryUsageStatsSection extends PowerStatsSpan.Section {
    public static final String TYPE = "battery-usage-stats";
    private static final String TAG = "BatteryUsageStatsSection";

    private final BatteryUsageStats mBatteryUsageStats;

@@ -50,6 +52,15 @@ class BatteryUsageStatsSection extends PowerStatsSpan.Section {
        mBatteryUsageStats.dump(ipw, "");
    }

    @Override
    public void close() {
        try {
            mBatteryUsageStats.close();
        } catch (IOException e) {
            Slog.e(TAG, "Closing BatteryUsageStats", e);
        }
    }

    static class Reader implements PowerStatsSpan.SectionReader {
        @Override
        public String getType() {
Loading