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

Commit 1e725a7e authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Battery stats: wakeup alarm tracking, general cleanup.

Instead of just tracking the total number of wakeup alarms
per package, track a count for each tag.  Note this is only
wakeup alarms, not non-wakeup alarms.

Also tighten up the code a bit by exposing the actual ArrayMap
container through most of the BatteryStats API, so we can more
efficiently iterate over them (which is all we ever want to do
with those containers at that point).

Finally remove all printing of "since unplugged" stats, as
another step towards completely removing that tracking.  If
nobody screams, hopefully soon we can go through and just get
rid of all the extra state we are carrying around that is
tracking that data.

Also note that currently the per-tag wakeup alarm data is
being reported in the human-readable stats, but in the checkin
data it is still being rolled up into a single number.  To fix
this, I need to completely rework the pkg entry line to have
separate data for services and wakeup alarms (so have three
types -- pkg for the start of a package, wal for a wakeup
alarm, svc for a service).

Change-Id: I8033acca8742935cfe95511cdea730a405b17cab
parent e4df25ed
Loading
Loading
Loading
Loading
+434 −458

File changed.

Preview size limit exceeded, changes collapsed.

+66 −75
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ public final class BatteryStatsImpl extends BatteryStats {
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'

    // Current on-disk Parcel version
    private static final int VERSION = 121 + (USE_OLD_HISTORY ? 1000 : 0);
    private static final int VERSION = 122 + (USE_OLD_HISTORY ? 1000 : 0);

    // Maximum number of items we will record in the history.
    private static final int MAX_HISTORY_ITEMS = 2000;
@@ -494,8 +494,7 @@ public final class BatteryStatsImpl extends BatteryStats {
     * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
     * to mKernelWakelockStats.
     */
    private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
            new HashMap<String, KernelWakelockStats>();
    private final Map<String, KernelWakelockStats> mProcWakelockFileStats = new HashMap<>();

    private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
    private NetworkStats mCurMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
@@ -4607,17 +4606,17 @@ public final class BatteryStatsImpl extends BatteryStats {
        }

        @Override
        public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
        public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
            return mWakelockStats.getMap();
        }

        @Override
        public Map<String, ? extends BatteryStats.Timer> getSyncStats() {
        public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() {
            return mSyncStats.getMap();
        }

        @Override
        public Map<String, ? extends BatteryStats.Timer> getJobStats() {
        public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() {
            return mJobStats.getMap();
        }

@@ -4627,12 +4626,12 @@ public final class BatteryStatsImpl extends BatteryStats {
        }

        @Override
        public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
        public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
            return mProcessStats;
        }

        @Override
        public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
        public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
            return mPackageStats;
        }

@@ -6153,40 +6152,20 @@ public final class BatteryStatsImpl extends BatteryStats {
         */
        public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
            /**
             * Number of times this package has done something that could wake up the
             * device from sleep.
             * Number of times wakeup alarms have occurred for this app.
             */
            int mWakeups;

            /**
             * Number of things that could wake up the device loaded from a
             * previous save.
             */
            int mLoadedWakeups;

            /**
             * Number of things that could wake up the device as of the
             * last run.
             */
            int mLastWakeups;

            /**
             * Number of things that could wake up the device as of the
             * last run.
             */
            int mUnpluggedWakeups;
            ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();

            /**
             * The statics we have collected for this package's services.
             */
            final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
            final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>();

            Pkg() {
                mOnBatteryScreenOffTimeBase.add(this);
            }

            public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
                mUnpluggedWakeups = mWakeups;
            }

            public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
@@ -6197,10 +6176,12 @@ public final class BatteryStatsImpl extends BatteryStats {
            }

            void readFromParcelLocked(Parcel in) {
                mWakeups = in.readInt();
                mLoadedWakeups = in.readInt();
                mLastWakeups = 0;
                mUnpluggedWakeups = in.readInt();
                int numWA = in.readInt();
                mWakeupAlarms.clear();
                for (int i=0; i<numWA; i++) {
                    String tag = in.readString();
                    mWakeupAlarms.put(tag, new Counter(mOnBatteryTimeBase, in));
                }

                int numServs = in.readInt();
                mServiceStats.clear();
@@ -6214,34 +6195,39 @@ public final class BatteryStatsImpl extends BatteryStats {
            }

            void writeToParcelLocked(Parcel out) {
                out.writeInt(mWakeups);
                out.writeInt(mLoadedWakeups);
                out.writeInt(mUnpluggedWakeups);

                out.writeInt(mServiceStats.size());
                for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
                    out.writeString(servEntry.getKey());
                    Uid.Pkg.Serv serv = servEntry.getValue();
                int numWA = mWakeupAlarms.size();
                out.writeInt(numWA);
                for (int i=0; i<numWA; i++) {
                    out.writeString(mWakeupAlarms.keyAt(i));
                    mWakeupAlarms.valueAt(i).writeToParcel(out);
                }

                final int NS = mServiceStats.size();
                out.writeInt(NS);
                for (int i=0; i<NS; i++) {
                    out.writeString(mServiceStats.keyAt(i));
                    Uid.Pkg.Serv serv = mServiceStats.valueAt(i);
                    serv.writeToParcelLocked(out);
                }
            }

            @Override
            public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
                return mServiceStats;
            public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() {
                return mWakeupAlarms;
            }

            @Override
            public int getWakeups(int which) {
                int val = mWakeups;
                if (which == STATS_CURRENT) {
                    val -= mLoadedWakeups;
                } else if (which == STATS_SINCE_UNPLUGGED) {
                    val -= mUnpluggedWakeups;
            public void noteWakeupAlarmLocked(String tag) {
                Counter c = mWakeupAlarms.get(tag);
                if (c == null) {
                    c = new Counter(mOnBatteryTimeBase);
                    mWakeupAlarms.put(tag, c);
                }
                c.stepAtomic();
            }

                return val;
            @Override
            public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
                return mServiceStats;
            }

            /**
@@ -6483,14 +6469,6 @@ public final class BatteryStatsImpl extends BatteryStats {
                }
            }

            public BatteryStatsImpl getBatteryStats() {
                return BatteryStatsImpl.this;
            }

            public void incWakeupsLocked() {
                mWakeups++;
            }

            final Serv newServiceStatsLocked() {
                return new Serv();
            }
@@ -8938,7 +8916,18 @@ public final class BatteryStatsImpl extends BatteryStats {
            for (int ip = 0; ip < NP; ip++) {
                String pkgName = in.readString();
                Uid.Pkg p = u.getPackageStatsLocked(pkgName);
                p.mWakeups = p.mLoadedWakeups = in.readInt();
                final int NWA = in.readInt();
                if (NWA > 1000) {
                    Slog.w(TAG, "File corrupt: too many wakeup alarms " + NWA);
                    return;
                }
                p.mWakeupAlarms.clear();
                for (int iwa=0; iwa<NWA; iwa++) {
                    String tag = in.readString();
                    Counter c = new Counter(mOnBatteryTimeBase);
                    c.readSummaryFromParcelLocked(in);
                    p.mWakeupAlarms.put(tag, c);
                }
                NS = in.readInt();
                if (NS > 1000) {
                    Slog.w(TAG, "File corrupt: too many services " + NS);
@@ -9263,14 +9252,17 @@ public final class BatteryStatsImpl extends BatteryStats {
                    : u.mPackageStats.entrySet()) {
                    out.writeString(ent.getKey());
                    Uid.Pkg ps = ent.getValue();
                    out.writeInt(ps.mWakeups);
                    final int NWA = ps.mWakeupAlarms.size();
                    out.writeInt(NWA);
                    for (int iwa=0; iwa<NWA; iwa++) {
                        out.writeString(ps.mWakeupAlarms.keyAt(iwa));
                        ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out);
                    }
                    NS = ps.mServiceStats.size();
                    out.writeInt(NS);
                    if (NS > 0) {
                        for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
                                : ps.mServiceStats.entrySet()) {
                            out.writeString(sent.getKey());
                            BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
                    for (int is=0; is<NS; is++) {
                        out.writeString(ps.mServiceStats.keyAt(is));
                        BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
                        long time = ss.getStartTimeToNowLocked(
                                mOnBatteryTimeBase.getUptime(NOW_SYS));
                        out.writeLong(time);
@@ -9281,7 +9273,6 @@ public final class BatteryStatsImpl extends BatteryStats {
            }
        }
    }
    }

    public void readFromParcel(Parcel in) {
        readFromParcelLocked(in);
+33 −22
Original line number Diff line number Diff line
@@ -6326,14 +6326,23 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
        try {
            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
            Intent intent = res.key.requestIntent;
            synchronized (this) {
                return getTagForIntentSenderLocked(res, prefix);
            }
        } catch (ClassCastException e) {
        }
        return null;
    }
    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
        final Intent intent = res.key.requestIntent;
        if (intent != null) {
            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
                    || res.lastTagPrefix.equals(prefix))) {
                return res.lastTag;
            }
            res.lastTagPrefix = prefix;
                StringBuilder sb = new StringBuilder(128);
            final StringBuilder sb = new StringBuilder(128);
            if (prefix != null) {
                sb.append(prefix);
            }
@@ -6346,8 +6355,6 @@ public final class ActivityManagerService extends ActivityManagerNative
            }
            return res.lastTag = sb.toString();
        }
        } catch (ClassCastException e) {
        }
        return null;
    }
@@ -10479,17 +10486,21 @@ public final class ActivityManagerService extends ActivityManagerNative
        if (!(sender instanceof PendingIntentRecord)) {
            return;
        }
        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
        final PendingIntentRecord rec = (PendingIntentRecord)sender;
        final String tag;
        synchronized (this) {
            tag = getTagForIntentSenderLocked(rec, "*walarm*:");
        }
        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
        synchronized (stats) {
            if (mBatteryStatsService.isOnBattery()) {
                mBatteryStatsService.enforceCallingPermission();
                PendingIntentRecord rec = (PendingIntentRecord)sender;
                int MY_UID = Binder.getCallingUid();
                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
                BatteryStatsImpl.Uid.Pkg pkg =
                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
                            sourcePkg != null ? sourcePkg : rec.key.packageName);
                pkg.incWakeupsLocked();
                pkg.noteWakeupAlarmLocked(tag);
            }
        }
    }
+2 −6
Original line number Diff line number Diff line
@@ -772,12 +772,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub

    private void dumpHelp(PrintWriter pw) {
        pw.println("Battery stats (batterystats) dump options:");
        pw.println("  [--checkin] [--history] [--history-start] [--unplugged] [--charged] [-c]");
        pw.println("  [--checkin] [--history] [--history-start] [--charged] [-c]");
        pw.println("  [--daily] [--reset] [--write] [--new-daily] [--read-daily] [-h] [<package.name>]");
        pw.println("  --checkin: format output for a checkin report.");
        pw.println("  --history: show only history data.");
        pw.println("  --history-start <num>: show only history data starting at given time offset.");
        pw.println("  --unplugged: only output data since last unplugged.");
        pw.println("  --charged: only output data since last charged.");
        pw.println("  --daily: only output full daily data.");
        pw.println("  --reset: reset the stats, clearing all current data.");
@@ -856,8 +855,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub
                } else if ("-c".equals(arg)) {
                    useCheckinFormat = true;
                    flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
                } else if ("--unplugged".equals(arg)) {
                    flags |= BatteryStats.DUMP_UNPLUGGED_ONLY;
                } else if ("--charged".equals(arg)) {
                    flags |= BatteryStats.DUMP_CHARGED_ONLY;
                } else if ("--daily".equals(arg)) {
@@ -931,8 +928,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
        if (reqUid >= 0) {
            // By default, if the caller is only interested in a specific package, then
            // we only dump the aggregated data since charged.
            if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_UNPLUGGED_ONLY
                    |BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
            if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
                flags |= BatteryStats.DUMP_CHARGED_ONLY;
                // Also if they are doing -c, we don't want history.
                flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY;